为什么构造的委托类的Invoke方法是virtual的?

发布于 2024-12-06 22:04:43 字数 569 浏览 0 评论 0原文

我在 CLR via C# 和 codeproject 文章幕后委托,当 C# 编译器看到它时,

public delegate void MyDelegate(int intValue);

它实际上会生成一些东西就像这个

class MyDelegate : System.MulticastDelegate
{
    public virtual void Invoke(Int32 intValue);

    ...
}

问题一样,为什么 Invoke 方法是虚拟的?这个生成的委托类型可以继承吗?从CLR的角度看起来是可以的。但为什么?为什么不生成密封类,这样在运行时就不会出现虚拟方法查找损失?

I've seen in CLR via C# and in codeproject article Delegate Behind the Scenes that when C# compiler sees this

public delegate void MyDelegate(int intValue);

it actually generates something like this

class MyDelegate : System.MulticastDelegate
{
    public virtual void Invoke(Int32 intValue);

    ...
}

Question is, why Invoke method is virtual? Can this generated delegate type be inherited? From the CLR point of view looks like it can. But why? Why not generating sealed class so there will be no virtual methods lookup penalty at runtime?

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

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

发布评论

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

评论(2

弄潮 2024-12-13 22:04:44

这是鸭子般的嘎嘎打字。类似类型的类型使 System.Int32(一种值类型)派生自 ValueType(一种引用类型)。没有意义,在 C# 中是非法的,但实际上是这样的。委托的 Invoke 方法的真正实现隐藏在 CLR 中,并且是用 C++ 编写的静态函数。

但可以肯定的是,将其注释为 virtual 是有一定意义的,因为它的行为类似于虚拟方法。实际执行的代码并不像非虚拟类方法那样固定。更难推理出绑定到静态方法的委托的正确模型应该是什么。静态的虚拟方法?

它只是一只虚拟的鸭子。

阅读 C 中使用的函数指针可以帮助您为委托获得更好的心智模型。委托是一个带有响铃的函数指针,它也可以存储目标对象。 C# 缺乏以另一种方式表达这一点的语法。

This is quacks-like-a-duck typing. Similar kind of typing that makes System.Int32, a value type, derived from ValueType, a reference type. Makes no sense, illegal in C#, but actually behaves that way. The real implementation of a delegate's Invoke method is buried in the CLR and is a static function written in C++.

But sure, annotating it as virtual makes somewhat sense because it behaves like a virtual method. The actual code that executes is not fixed like it is with a non-virtual class method. Even harder to reason out is what the proper model should be for a delegate that's bound to a static method. A virtual method that's static?

It is just a virtual duck.

Reading up on function pointers as used in C could help you get a better mental model for delegates. A delegate is a function pointer with bells on, it can also store the target object. C# lacks the syntax to express this another way.

-黛色若梦 2024-12-13 22:04:44

以下是 Eric Lippert 关于 .NET 中的继承的有趣引用:

我偶尔会被问到“但是像 int 这样的值类型怎么能
32位内存,不多也不少,可能是继承自object?一个
内存中的对象比 32 位大得多;它有一个同步
块和一个虚函数表以及里面的各种东西。”
显然很多人认为继承与继承有关
以及值在内存中的布局方式。但价值是如何布置的
内存是一个实现细节,而不是合同义务
继承关系!

.NET 中有许多“特殊”继承类型:System.ValueTypeSystem.EnumSystem.Void>System.Delegate,其中我确信。

使用 Reflector.NET 查看 System.Delegate 的内部结构,我可以看到许多这样的调用:

[MethodImpl(MethodImplOptions.InternalCall), SecurityCritical]
internal static extern MulticastDelegate InternalAlloc(RuntimeType type);

我怀疑我们正在处理不同的实现细节,不需要委托使用虚拟方法需要使用的相同虚拟查找表。

Here's an interesting quote from Eric Lippert about inheritance in .NET:

I am occasionally asked "but how can a value type, like int, which is
32 bits of memory, no more, no less, possibly inherit from object? An
object laid out in memory is way bigger than 32 bits; it's got a sync
block and a virtual function table and all kinds of stuff in there."
Apparently lots of people think that inheritance has something to do
with how a value is laid out in memory. But how a value is laid out in
memory is an implementation detail, not a contractual obligation of
the inheritance relationship!

There are a number of "special" inherited types in .NET: System.ValueType, System.Enum,System.Void, and System.Delegate, amongst others I'm sure.

Taking a look at the internals of System.Delegate with Reflector.NET I can see a number of calls like this:

[MethodImpl(MethodImplOptions.InternalCall), SecurityCritical]
internal static extern MulticastDelegate InternalAlloc(RuntimeType type);

I suspect that we're dealing with a different implementation detail that doesn't require delegates to use the same virtual look up tables that virtual methods need to use.

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