代码之家  ›  专栏  ›  技术社区  ›  rerun

首选样式(抽象类或接口上的委托)

  •  0
  • rerun  · 技术社区  · 14 年前

    我正在写一个实用类库。我们已经编写了一个足够通用的工厂类,通过调用方传入的几个委托,它可以在许多不同的情况下重用。然而,我的一个同事建议我使用一个抽象类或接口,这样就可以更明确地说明需要重写哪些函数。在我创建的使用库的模型中,您需要重写2个类,而不是一个类。什么标准决定何时适合使用委托函数或接口。

    使用代理模式。


    Class A 
    {
        Func<string , ReultClass> fun1 {get;set;}
    
        FactoryObj CreateObj()
        {
             return fun1("")
        }
    }
    

    使用接口模式

    Class B 
    {
        InterfaceObj{get;set;}
    
        FactoryObj CreateObj()
        {
             return InterfaceObj.fun1("")
        }
    }
    
    4 回复  |  直到 14 年前
        1
  •  1
  •   Stephen Cleary    14 年前

    interface IA
    {
        ResultClass Fun1(string arg);
    }
    

    在这种情况下,您仍然可以使用委托;我通常使用显式接口实现编写“匿名”类(如Microsoft所称),因此委托属性的名称与其实现的接口方法的名称相同:

    class AnonymousA : IA
    { 
        Func<string, ResultClass> Fun1 { get; set; }
        ResultClass IA.Fun1(string arg) { return this.Fun1(arg); }
    } 
    

    如果涉及到泛型(例如。, IA<ResultClass> 以及相应的 AnonymousA<ResultClass> ),则定义工厂类非常有用,只需清理创建语法即可:

    static class Anonymous
    {
        public static IA<ResultClass> A<ResultClass>(Func<string, ResultClass> fun1)
        { return new AnonymousA<ResultClass> { Fun1 = fun1 }
    }
    
        2
  •  1
  •   Tejs    14 年前

    我想你会想更改方法的签名。不要将委托作为类的属性,而是将其作为需要传入的参数。然后,如果不传入所需的数据,甚至不能调用CreateObj方法,签名本身会告诉您需要传递什么才能使方法调用成功。

        3
  •  0
  •   James Manning    14 年前

    不幸的是,正如SLaks提到的,这有点取决于具体情况——很难做出任何笼统的陈述——甚至在某些情况下,上面的陈述也可能是个坏主意:)

        4
  •  0
  •   supercat    13 年前

    一种方法是维护MethodInvoker委托的列表,并依次调用每个委托(*)。如果清理需要对某个对象调用Dispose,请为该对象创建一个新的委托。Dispose()并将其添加到列表中。另一种方法是保留IDisposable对象的列表,并通过创建名为InvokeOnDispose的类来处理其他操作,该类包含MethodInvoker,并在调用Dispose时调用它。

    前一种方法需要为每个清理操作创建一个新的委托,不管它是简单地调用Dispose还是执行其他操作。在将IDisposable对象添加到列表时,后一种方法不需要创建任何新的对象实例,但是添加一些其他操作需要在委托之外创建InvokeOnDispose对象。

    (*)可以简单地使用MulticastDelegate,而不是委托列表,但在某些情况下(如对象清理),从一个清理操作引发的异常可能不会中断其他操作。虽然可以使用MulticastDelegate组装清理操作的集合,然后使用GetInvocationList在单独的“try-catch”块中运行每个操作,但是简单地使用get-go中的代理列表将更容易、更有效。