在.NET中,委托的内部实现是什么?

ric*_*ard 18 .net c# implementation delegates internal

我理解委托人的声明是这样的:

public delegate int PerformCalculation(int x, int y);
Run Code Online (Sandbox Code Playgroud)

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

这个参考是什么类型的结构(代表内部)?我也明白你可以在委托中封装对多个方法的引用.这是否意味着委托中有一个包含这些数组的数组?

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

public delegate int PerformCalculation(int x, int y);
Run Code Online (Sandbox Code Playgroud)

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

Han*_*ant 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) {}
}
Run Code Online (Sandbox Code Playgroud)

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

这里有很多秘密酱油.

  • 很难说,调试器在调试此代码方面非常糟糕.肯定有开销,它不是一个简单的虚方法调用.Afaict,它调用jitted Invoke()方法,然后对thunk进行间接调用,该thunk按摩堆栈帧并调用正确的调用者,具体取决于它是Delegate还是MulticastDelegate.后者需要迭代调用列表.当我对它进行分析(纳秒)时它非常便宜,但肯定不像方法调用那么便宜. (2认同)

Dar*_*rov 8

所有委托都从System.Delegate类型继承,该类型包含TargetMethod.更准确地说,他们从继承System.MultiCastDelegate从继承System.Delegate.

  • 谢谢!这正是我正在寻找的.我没有找到自己,我感到愚蠢.我似乎无法找到委托如何拥有多个引用.它有一个目标和一个方法,但这些看起来不像集合...我在这里错过了什么? (2认同)
  • 他们没有实施 - 他们继承. (2认同)