C# 委托类型的方法是如何在内部生成的?
我知道委托类型继承自MulticastDelegate,而MulticastDelegate又继承自delegate类 另外,当我们创建委托实例时,它会创建三个具有委托相同签名的方法(Invoke、BeginInvoke、EndInvoke和constructor) 我无法理解它是如何在内部创建的(具有委托类型签名的方法)C# 委托类型的方法是如何在内部生成的?,c#,delegates,C#,Delegates,我知道委托类型继承自MulticastDelegate,而MulticastDelegate又继承自delegate类 另外,当我们创建委托实例时,它会创建三个具有委托相同签名的方法(Invoke、BeginInvoke、EndInvoke和constructor) 我无法理解它是如何在内部创建的(具有委托类型签名的方法) 提前感谢。例如,我们有一位这样的代表: public delegate int BinaryOp(int x, int y); .class public sealed S
提前感谢。例如,我们有一位这样的代表:
public delegate int BinaryOp(int x, int y);
.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 {}
}
编译器如何知道如何定义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接口。例如,我们有这样一个委托:
public delegate int BinaryOp(int x, int y);
.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 {}
}
编译器如何知道如何定义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接口。如果您查看Reflector或ILSpy中委托类型的IL,您将看到它的外观如下:
public delegate int BinaryOp(int x, int y);
.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
关键字向CLR指示此方法需要CLR本身提供的实现。也就是说,委托的实现在CLR本身中是完全神奇的。加载委托类型时,CLR会注意到它派生自System.delegate
,注意到runtime
标志,从而在CLR内为该特定委托类型创建这些方法的实现
这些实现的实际外观完全取决于运行它的CLR(无论是.NET平台、Mono还是其他平台),但很可能直接在本机代码中
当编译器编译委托类型时,它只创建这些方法存根以匹配CLR所期望的模式,并将其保留。委托的实际工作方式取决于运行时。如果您查看Reflector或ILSpy中委托类型的IL,您将看到它的外观如下:
public delegate int BinaryOp(int x, int y);
.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
关键字向CLR指示此方法需要CLR本身提供的实现。也就是说,委托的实现在CLR本身中是完全神奇的。加载委托类型时,CLR会注意到它派生自System.delegate
,注意到runtime
标志,从而在CLR内为该特定委托类型创建这些方法的实现
这些实现的实际外观完全取决于运行它的CLR(无论是.NET平台、Mono还是其他平台),但很可能直接在本机代码中
当编译器编译委托类型时,它只创建这些方法存根以匹配CLR所期望的模式,并将其保留。委托的实际工作方式取决于运行时。委托是如何创建的-代码由C#编译器发出。你还需要知道什么?它是如何创建的——代码是由C#编译器发出的。您还需要知道什么?您的意思是说编译器将负责生成具有正确参数的方法?是的。编译器将查看委托的返回类型和参数,并相应地创建方法。例如,如果两个参数的类型为char,则生成的类中的方法将具有char类型的参数。请看这个问题:您的意思是说编译器将负责生成具有正确参数的方法?是的。编译器将查看委托的返回类型和参数,并相应地创建方法。例如,如果其中的两个参数为char类型,则生成的类中的方法将具有char类型的参数。请看以下问题: