Должен ли я сделать метод `GetObjectData` виртуальным явно в C#? - PullRequest
1 голос
/ 15 марта 2020

Должен ли я сделать метод GetObjectData виртуальным явно в C#?

В книге CLR через C# я встретил следующую выдержку:

Если ваш производный тип не содержит каких-либо дополнительных полей и поэтому не нуждается в особых сериализационных / десериализационных потребностях, тогда вам вообще не нужно реализовывать ISerializable. Как и все члены интерфейса, GetObjectData является виртуальным и будет вызываться для правильной сериализации объекта. Кроме того, средство форматирования рассматривает специальный конструктор как «виртуализированный». То есть во время десериализации средство форматирования проверяет тип, который он пытается создать. Если этот тип не предлагает специальный конструктор, то средство форматирования будет сканировать базовые классы, пока не найдет тот, который реализует специальный конструктор.

Как я знаю ( source ), методы интерфейса не являются виртуальными по умолчанию. Итак, почему мы должны сказать следующее Как и все члены интерфейса, GetObjectData является виртуальным ? Означает ли это, что когда существует какой-либо интерфейсный метод, связанный с сериализацией / десериализацией, мы должны сделать его виртуальным или это означает что-то другое?

1 Ответ

1 голос
/ 15 марта 2020

Это означает, что метод 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 к методу в вашем классе реализации, чтобы сделать его виртуальным, если метод должен быть виртуальным.

ОБНОВЛЕНИЕ

IL реализации по умолчанию 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

Реализация по умолчанию final и virtual, Это означает, что метод не может быть переопределен в производных классах по умолчанию. Добавление ключевого слова virtual к методу реализации удаляет final.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...