Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 委托类型的方法是如何在内部生成的?_C#_Delegates - Fatal编程技术网

C# 委托类型的方法是如何在内部生成的?

C# 委托类型的方法是如何在内部生成的?,c#,delegates,C#,Delegates,我知道委托类型继承自MulticastDelegate,而MulticastDelegate又继承自delegate类 另外,当我们创建委托实例时,它会创建三个具有委托相同签名的方法(Invoke、BeginInvoke、EndInvoke和constructor) 我无法理解它是如何在内部创建的(具有委托类型签名的方法) 提前感谢。例如,我们有一位这样的代表: public delegate int BinaryOp(int x, int y); .class public sealed S

我知道委托类型继承自MulticastDelegate,而MulticastDelegate又继承自delegate类

另外,当我们创建委托实例时,它会创建三个具有委托相同签名的方法(Invoke、BeginInvoke、EndInvoke和constructor)

我无法理解它是如何在内部创建的(具有委托类型签名的方法)


提前感谢。

例如,我们有一位这样的代表:

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类型的参数。请看以下问题: