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

发布于 2024-11-30 20:22:29 字数 207 浏览 0 评论 0原文

我知道委托类型是从 MulticastDelegate 继承的,而 MulticastDelegate 又是从 Delegate 类继承的。

此外,当我们创建委托实例时,它会创建三个具有相同委托签名的方法(Invoke、BeginInvoke、EndInvoke 除了构造函数)。

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

提前致谢。

I know delegate type is inherited from MulticastDelegate which is in turn inherited from Delegate class.

Also when we create delegate instance it creates three methods (Invoke, BeginInvoke, EndInvoke apart from constructor) with the same signature of the delegate.

I am not able to understand how it is created internally(methods with delegate type signature)?

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

红尘作伴 2024-12-07 20:22:29

如果您查看 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< /code> 和 BeginInvoke/EndInvoke 方法。您还会注意到,这些方法没有实现(方法主体为空),并用 runtime 标记。

runtime 关键字向 CLR 指示该方法需要由 CLR 本身提供的实现。也就是说,委托的实现完全是 CLR 本身内部的 Magic。加载委托类型时,CLR 会注意到它派生自 System.Delegate,注意到 runtime 标志,因此会在 CLR 内为该特定创建这些方法的实现。委托类型。

这些实现实际上看起来完全取决于您运行它的 CLR(无论是 .NET 平台、Mono 还是其他平台),但很可能直接采用本机代码。

当编译器编译委托类型时,它只是创建这些方法存根来匹配 CLR 所期望的模式,然后将其保留。委托的实际工作方式取决于运行时。

If you have a look at the IL of a delegate type in Reflector or ILSpy, you'll see that it looks something like this:

.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 {}
}

that is, a constructor (.ctor), Invoke, and BeginInvoke/EndInvoke methods. You'll also notice that these methods have no implementation (the method bodies are empty), and are marked with runtime.

The runtime keyword indicates to the CLR that this method needs an implementation supplied by the CLR itself. That is, the implementation of a delegate is entirely Magic inside the CLR itself. When a delegate type is loaded, the CLR notices that it derives from System.Delegate, notices the runtime flag, and so creates implementations of those methods inside the CLR for that specific delegate type.

What those implementations actually look like is entirely up to the CLR you're running it on (whether the .NET platform, Mono, or something else), but is likely to be in native code directly.

When a compiler compiles a delegate type, it simply creates these method stubs to match this pattern expected by the CLR, and leaves it at that. How a delegate actually works is up to the runtime.

只涨不跌 2024-12-07 20:22:29

举例来说,我们有一个这样的委托:

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 类型和对象类型),用于促进异步方法调用。

最后,EndInvoke()的返回值与原始值相同
委托声明并且始终将实现该对象的对象作为唯一参数
IAsyncResult 接口。

Lets say for example, we have a delegate like this:

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

How does the compiler know how to define the Invoke(), BeginInvoke(), and
EndInvoke() methods?

This is the generated class by the compiler:

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);
}

First, notice that the parameters and return value defined for the Invoke() method exactly
match the definition of the BinaryOp delegate.

The initial parameters to BeginInvoke() members (two integers in our case) are also based on the BinaryOp delegate;
however, BeginInvoke() will always provide two final parameters (of type AsyncCallback and object) that are used to facilitate asynchronous method invocations.

Finally, the return value of EndInvoke() is identical to the original
delegate declaration and will always take as a sole parameter an object implementing the
IAsyncResult interface.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文