2010-09-17 43 views
2

我理解代表作为使用一种方法定义类的快捷方式,但以下bar2的含义是什么?它编译。但我看不出内部班会在这里做什么。我知道我错过了一些东西,这就是为什么我要问(这不是家庭作业,我现在正在工作)。一个代表在课堂内的含义是什么?

namespace ns2 { public delegate void bar();} 
public class foo 
{ 
    private ns2.bar _callback; 
    public foo(ns2.bar callback) { _callback = callback; } 
    public void baz() { _callback(); } 
    public delegate void bar2(); 
} 

谢谢!

回答

6

这只是声明一个嵌套类型,就这些。由于它是公开的,在类型中声明和在外部声明之间几乎没有区别。

其他类人员都将通过包含类型的名称来指代它(除非他们有一个using指令专门为它):

public class OtherClass 
{ 
    private void DoSomething() 
    { 
     foo.bar2 action = delegate { ... }; 
     foo f = new foo(action); 
     ... 
    } 
} 

通常当我写一个嵌套的类型,它是私有的 - 它只是包含类的助手类;一个实现细节。当然,情况并非如此,但至少应该是这样的,即嵌套类型是毫无意义的,除非您使用外部类的方式使用的某些。例如,它可以是外部类的构建器,也可以是外部类中的方法调用的某些参数中使用的枚举。

(顺便说一下,它编写的代码示例这样当遵循.NET命名约定,即使对于像FooBar元语法名称是非常有用的,它使变量和类型更清晰的区别,例如。)

+0

感谢您的答案和提示。 – 2010-09-17 16:54:31

7

委托并不是用一种方法定义类的快捷方式。它们实际上至少有6种方法(Invoke,BeginInvoke,EndInvoke,GetHashCode,Equals,ToString)。

将代表放入某个类型的模式的一个原因是为了避免全局命名空间污染。代表bar2只能通过foo的合格参考进行访问。如果bar2是一个具有多个有效含义的名称并且将其放入foo以提供必要的上下文,则这可能很有用。

+0

+1,不喜欢使用一种方法定义类的快捷方式。必须是来自Java的匿名类的遗留。 – 2010-09-17 16:41:49

+2

将一个委托类型想象成一个*接口*,使用一个方法IMO,然后再为异步操作调用该方法更为合理。对我来说,代表正确的*感觉*。出于兴趣,保证'BeginInvoke',但'EndInvoke'不保证? – 2010-09-17 16:43:44

+0

@Jon,'EndInvoke'也有保证(更新我的答案)。 – JaredPar 2010-09-17 16:47:20

8

要添加到Jon和Jared的答案中,我注意到,通常在类中定义委托的唯一时间是委托是类的私有实现细节。在一个类中有一个public委托定义是罕见的和奇怪的。

例如,考虑我喜欢的图案:一个抽象基类,只能通过与工厂生产的私人嵌套类扩展:

public abstract class Animal 
{ 
    private Animal() { } // prevents subclassing from outside! 
    private sealed class Giraffe : Animal { } 
    private sealed class Leopard : Animal { } 
    public static Animal GetGiraffe() { return new Giraffe(); } 
    public static Animal GetLeopard() { return new Leopard(); } 

假设动物的实现细节是,你需要有从长颈鹿到豹的代表:

private delegate Leopard D(Giraffe g); 

这不能是公共委托类,因为它指的是私有类型!

现在当然你甚至不会这样做。你会使用Func<Giraffe, Leopard>,你就完成了。

因此,嵌套的委托类型几乎是为了完整性和向后兼容性;通常你不会使用它。