20

我知道代表的声明是这样的:

public delegate int PerformCalculation(int x, int y);

然而,必须有更多的事情发生。委托的目的是提供一个指向方法的指针,为此,您将对该方法的引用封装在委托中。

这个引用保存在什么样的结构中(在委托内部)?我也知道您可以在委托中封装对多个方法的引用。这是否意味着代表中有一个数组来保存这些?

此外,委托中定义了哪些方法等。当您使用简洁声明委托时真正发生了什么:

public delegate int PerformCalculation(int x, int y);

?

编辑:一些澄清。当你声明一个委托时,编译器会自动为你创建一个继承自 System.MulticastDelegate 的密封类。如果您使用 ildasm 查看您的程序集,您可以看到这一点。这整齐。基本上,通过一个语句,您将在编译时为您生成一个全新的类,它具有您需要的所有功能。

4

2 回答 2

19

在内部它是一个引用类型,非常类似于一个类。转录它看起来像这样:

public /* delegate */ class PerformCalculation : MulticastDelegate {
    public PerformCalculation(object target, IntPtr method) {}
    public virtual void Invoke(int x, int y) {}
    public virtual IAsyncResult BeginInvoke(int x, int y, AsyncCallback callback, object state) {}
    public virtual void EndInvoke(IAsyncResult result) {}
}

我将这些成员的实现留空,它们实际上映射到 CLR 中的代码。编译器根据委托声明的签名动态生成方法签名。注意 x 和 y 参数。JIT 编译器帮助调用构造函数,使用 += 或 -= 语法,它知道委托目标方法的内存地址。编译器根据目标方法是否为静态自动生成目标参数值。这两个参数映射到 (Multicast)Delegate.Target 和 Method 属性。实际的基类实例可以是 Delegate 或 MulticastDelegate,具体取决于订阅了多少目标。

这里有很多秘密酱汁。

于 2011-01-09T21:44:31.480 回答
9

所有委托都继承自System.Delegate类型,该类型包含TargetMethod。更准确地说,它们继承自System.MultiCastDelegate,后者继承自System.Delegate.

于 2011-01-09T21:30:10.997 回答