V3103. A private Ctor(SerializationInfo, StreamingContext) constructor in unsealed type will not be accessible when deserializing derived types.
Анализатор обнаружил странный модификатор доступа у конструктора сериализации.
Странными можно считать следующие ситуации:
- модификатор доступа – public;
- тип не запечатан (unsealed type), при этом его модификатор доступа – private.
Конструктор сериализации вызывается при десериализации объекта и не должен вызываться извне типа (исключение – вызов конструктора классом-наследником), поэтому не стоит объявлять его с модификатором 'public' или 'internal'.
Если конструктор объявлен с модификатором 'private', но класс не является запечатанным, классы-наследники не смогут вызывать этот конструктор, что приведёт к невозможности десериализации членов базового типа.
Рассмотрим пример:
[Serializable]
class C1 : ISerializable
{
....
private C1(SerializationInfo info, StreamingContext context)
{
....
}
....
}
Класс 'C1' является незапечатанным, но при этом конструктор сериализации объявлен с модификатором доступа 'private', что приведёт к невозможности вызова этого конструктора из дочерних классов и, как следствие, к неверной десериализации объекта. Для исправления ситуации необходимо исправить модификатор доступа на 'protected':
[Serializable]
class C1 : ISerializable
{
....
protected C1(SerializationInfo info, StreamingContext context)
{
....
}
....
}
Примечание. Для данной диагностики доступна дополнительная настройка, задающаяся в конфигурационном файле (*.pvsconfig), имеющая следующий синтаксис:
//+V3103:CONF:{ IncludeBaseTypes: true }
В таком случае анализатор просматривает не только непосредственно реализацию интерфейса 'ISerializable' самим классом, но и каким-либо из базовых. По умолчанию эта настройка отключена.
Дополнительную информацию о конфигурационных файлах можно прочитать здесь.