.net 为什么构造的委托类的Invoke方法是虚拟的?

.net 为什么构造的委托类的Invoke方法是虚拟的?,.net,compiler-construction,delegates,.net,Compiler Construction,Delegates,我在codeproject的文章中看到,当C#编译器看到这一点时 public delegate void MyDelegate(int intValue); 它实际上产生了类似这样的东西 class MyDelegate : System.MulticastDelegate { public virtual void Invoke(Int32 intValue); ... } 问题是,为什么调用方法是虚拟的?是否可以继承此生成的委托类型?从CLR的角度看,它似乎可以。但是

我在codeproject的文章中看到,当C#编译器看到这一点时

public delegate void MyDelegate(int intValue);
它实际上产生了类似这样的东西

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

    ...
}

问题是,为什么调用方法是虚拟的?是否可以继承此生成的委托类型?从CLR的角度看,它似乎可以。但是为什么呢?为什么不生成密封类,这样在运行时就不会有虚拟方法查找惩罚?

这是一种庸医式的键入。类似的类型,使System.Int32(一种值类型)从ValueType(一种引用类型)派生而来。毫无意义,在C#中是非法的,但实际上是这样的。委托调用方法的实际实现被埋入CLR中,是一个用C++编写的静态函数。 但是可以肯定的是,将其注释为virtual有一定的意义,因为它的行为类似于虚拟方法。实际执行的代码不像使用非虚拟类方法时那样是固定的。更难解释的是,对于绑定到静态方法的委托,正确的模型应该是什么。一个静态的虚拟方法

它只是一只虚拟的鸭子


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

这里有一段有趣的引用,来自.NET中的继承:

我偶尔会被问到“但是像int这样的值类型怎么可能是 32位内存,不多也不少,可能是从对象继承的?一个 内存中的对象比32位大得多;它有一个同步 块和虚拟函数表以及其中的各种内容。” 显然,很多人认为遗产与此有关 一个值在内存中的排列方式。但价值是如何在 内存是一个实现细节,而不是 继承关系

在.NET中有许多“特殊”继承类型:
System.ValueType
System.Enum
System.Void
,以及
System.Delegate
,我确信还有其他类型

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

[MethodImpl(MethodImplOptions.InternalCall), SecurityCritical]
internal static extern MulticastDelegate InternalAlloc(RuntimeType type);
我怀疑我们正在处理一个不同的实现细节,它不需要委托使用
virtual
方法需要使用的相同虚拟查找表