我应该在C#中将GetObjectData方法显式虚拟化吗?

问题描述 投票:1回答:1

是否应该在C#中将GetObjectData方法显式虚拟化?

通过C#的CLR书中,我遇到了以下摘录:

如果您的派生类型中没有任何其他字段,因此没有特殊之处序列化/反序列化的需要,那么您根本不必实现ISerializable像所有接口成员,GetObjectData是虚拟的,将被调用以正确序列化该对象。在此外,格式化程序将特殊构造函数视为“虚拟化”。也就是说,在反序列化过程中,格式化程序将检查其试图实例化的类型。如果该类型不提供特殊构造函数,则格式化程序将扫描基类,直到找到实现特殊构造函数的基类为止。

据我所知(source),默认情况下接口方法不是虚拟的。那么,为什么我们要说以下像所有接口成员一样,GetObjectData是虚拟的?这是否意味着当存在与序列化/反序列化相关的任何接口方法时,我们应该将其设置为虚拟还是意味着有所不同?

c# serialization interface deserialization virtual
1个回答
1
投票

这表示该接口上的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

默认情况下,实现为finalvirtual,这意味着默认情况下无法在派生类中重写该方法。在实现方法中添加virtual关键字会删除final

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.