我知道委托类型是从MulticastDelegate继承的,而MulticastDelegate又继承自Delegate类。
当我们创建委托实例时,它会创建三个方法(Invoke,BeginInvoke,EndInvoke,除了构造函数),并具有相同的委托签名。
我无法理解它是如何在内部创建的(具有委托类型签名的方法)?
提前致谢。
答案 0 :(得分:4)
如果你看一下Reflector或ILSpy中委托类型的IL,你会发现它看起来像这样:
.class public sealed System.Action extends System.MulticastDelegate
{
.method public hidebysig specialname rtspecialname instance void .ctor(object 'object', native int 'method') runtime managed {}
.method public hidebysig newslot virtual instance void Invoke() runtime managed {}
.method public hidebysig newslot virtual instance class System.IAsyncResult BeginInvoke(class System.AsyncCallback callback, object 'object') runtime managed {}
.method public hidebysig newslot virtual instance void EndInvoke(class System.IAsyncResult result) runtime managed {}
}
即构造函数(.ctor
),Invoke
和BeginInvoke/EndInvoke
方法。您还会注意到这些方法没有实现(方法体是空的),并标有runtime
。
runtime
关键字向CLR指示此方法需要CLR本身提供的实现。也就是说,委托的实现完全是在CLR本身内部的Magic。加载委托类型时,CLR会注意到它派生自System.Delegate
,注意到runtime
标志,因此在CLR中为该特定委托类型创建了这些方法的实现。
这些实现实际上看起来完全取决于您运行它的CLR(无论是.NET平台,Mono还是其他),但可能直接使用本机代码。
当编译器编译委托类型时,它只是创建这些方法存根以匹配CLR所期望的这种模式,并将其留在那里。委托的实际工作方式取决于运行时。
答案 1 :(得分:2)
让我们举例来说,我们有一个像这样的代表:
public delegate int BinaryOp(int x, int y);
编译器如何知道如何定义Invoke(),BeginInvoke()和 EndInvoke()方法?
这是编译器生成的类:
sealed class BinaryOp : System.MulticastDelegate
{
public BinaryOp(object target, uint functionAddress);
public int Invoke(int x, int y);
public IAsyncResult BeginInvoke(int x, int y,AsyncCallback cb, object state);
public int EndInvoke(IAsyncResult result);
}
首先,请注意为Invoke()方法准确定义的参数和返回值 匹配BinaryOp委托的定义。
BeginInvoke()成员的初始参数(在我们的例子中是两个整数)也基于BinaryOp委托;
但是,BeginInvoke()将始终提供两个用于促进异步方法调用的最终参数(类型为AsyncCallback和object)。
最后,EndInvoke()的返回值与原始值相同 委托声明,并始终将实现该声明的对象作为唯一参数 IAsyncResult接口。