Search code examples
c#serializationinterfacedeserializationvirtual

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


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

In the CLR via C# book I met the following excerpt:

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.

As I know (source), the interface methods are not virtual by default. So, why would we say the following Like all interface members, GetObjectData is virtual? Does it mean that when there is any interface method related to serialization/deserialization, then we should make it virtual or does it mean something different?


Solution

  • It means the GetObjectData method on that interface is virtual. By default, all methods on C# interfaces are virtual.

    For example, if there's an interface:

    interface IMyInterface
    { 
        void MyMethod();
    }
    

    The IL of the interface:

    .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 is by default marked as virtual.

    It doesn't mean that when the interface is implemented by a class, the class method will still be virtual. You will have to explicitly add virtual keyword to method on your implementation class to make it virtual if the method needs to be virtual.

    UPDATE

    IL of default implementation of MyMethod:

    .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
    

    The implementation is by default final and virtual, meaning that the method cannot be overridden in derived classes by default. Adding virtual keyword to the implementation method removes final.