为什么构造的委托类的Invoke方法是virtual的?
我在 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是鸭子般的嘎嘎打字。类似类型的类型使 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.
以下是 Eric Lippert 关于 .NET 中的继承的有趣引用:
.NET 中有许多“特殊”继承类型:
System.ValueType
、System.Enum
、System.Void
和>System.Delegate
,其中我确信。使用 Reflector.NET 查看
System.Delegate
的内部结构,我可以看到许多这样的调用:我怀疑我们正在处理不同的实现细节,不需要委托使用
虚拟
方法需要使用的相同虚拟查找表。Here's an interesting quote from Eric Lippert about inheritance in .NET:
There are a number of "special" inherited types in .NET:
System.ValueType
,System.Enum
,System.Void
, andSystem.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: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.