我应该在 C# 中显式地使 `GetObjectData` 方法成为虚拟方法吗?

Should I make the `GetObjectData` method virtual explicitly in C#?

我应该在 C# 中显式地使 GetObjectData 方法成为虚拟方法吗?

CLR via C# 一书中,我遇到了以下摘录:

If your derived type doesn’t have any additional fields in it and therefore has no special serialization/deserialization needs, then you do not have to implement ISerializable at all. Like all interface members, GetObjectData is virtual and will be called to properly serialize the object. In addition, the formatter treats the special constructor as “virtualized.” That is, during deserialization, the formatter will check the type that it is trying to instantiate. If that type doesn’t offer the special constructor, then the formatter will scan base classes until it finds one that implements the special constructor.

据我所知(source),默认情况下接口方法不是虚拟的。那么,为什么我们会说下面的和所有接口成员一样,GetObjectData是虚拟的呢?是指当有任何接口方法与serialization/deserialization相关时,我们就应该将其虚拟化还是意味着不同的东西?

表示该接口上的GetObjectData方法是虚拟的。默认情况下,C# 接口上的所有方法都是虚拟的。

例如,如果有一个接口:

interface IMyInterface
{ 
    void MyMethod();
}

接口IL:

.class interface nested private auto ansi abstract IMyInterface
{
    // Methods
    .method public hidebysig newslot abstract virtual 
        instance void MyMethod () cil managed 
    {
    } // end of method IMyInterface::MyMethod

} // end of class IMyInterface

MyMethod 默认标记为 virtual.

并不意味着当接口被class实现时,class方法仍然是virtual。如果方法需要是虚拟的,则必须在实现 class 的方法中显式添加 virtual 关键字以使其成为虚拟的。

更新

MyMethod 默认实现的 IL:

.method public final hidebysig newslot virtual 
        instance void MyMethod () cil managed 
    {
        // Method begins at RVA 0x2050
        // Code size 2 (0x2)
        .maxstack 8

        IL_0000: nop
        IL_0001: ret
    } // end of method MyClass::MyMethod

实现默认为finalvirtual,意思是默认情况下不能在派生的classes中重写该方法。在实现方法中添加 virtual 关键字会删除 final.