是否应该在C#中将GetObjectData
方法显式虚拟化?
在通过C#的CLR书中,我遇到了以下摘录:
如果您的派生类型中没有任何其他字段,因此没有特殊之处序列化/反序列化的需要,那么您根本不必实现
ISerializable
。 像所有接口成员,GetObjectData
是虚拟的,将被调用以正确序列化该对象。在此外,格式化程序将特殊构造函数视为“虚拟化”。也就是说,在反序列化过程中,格式化程序将检查其试图实例化的类型。如果该类型不提供特殊构造函数,则格式化程序将扫描基类,直到找到实现特殊构造函数的基类为止。
据我所知(source),默认情况下接口方法不是虚拟的。那么,为什么我们要说以下像所有接口成员一样,GetObjectData
是虚拟的?这是否意味着当存在与序列化/反序列化相关的任何接口方法时,我们应该将其设置为虚拟还是意味着有所不同?
这表示该接口上的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
。
这并不意味着当接口由类实现时,该类方法仍将是虚拟的。如果方法需要是虚拟的,则必须在实现类上的方法上显式添加virtual
关键字,以使其成为虚拟的。
UPDATE
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
默认情况下,实现为final
和virtual
,这意味着默认情况下无法在派生类中重写该方法。在实现方法中添加virtual
关键字会删除final
。