V3094. Possible exception when deserializing type. The Ctor(SerializationInfo, StreamingContext) constructor is missing.
The analyzer detected a suspicious class implementing the 'ISerializable' interface but lacking a serialization constructor.
A serialization constructor is used for object deserialization and receives 2 parameters of types 'SerializationInfo' and 'StreamingContext'. When inheriting from this interface, the programmer is obliged to implement method 'GetObjectData' but is not obliged to implement a serialization constructor. However, if this constructor is missing, a 'SerializationException' will be raised.
Consider the following example. Suppose we have declared a method to handle object serialization and deserialization:
static void Foo(MemoryStream ms, BinaryFormatter bf, C1 obj)
{
bf.Serialize(ms, obj);
ms.Position = 0;
obj = (C1)bf.Deserialize(ms);
}
The 'C1' class itself is declared as follows:
[Serializable]
sealed class C1 : ISerializable
{
public C1()
{ }
public void GetObjectData(SerializationInfo info,
StreamingContext context)
{
info.AddValue("field", field, typeof(String));
}
private String field;
}
When attempting to deserialize the object, a 'SerializationException' will be thrown. To ensure correct deserialization of an object of type 'C1', a special constructor is required. A correct class declaration should then look like this:
[Serializable]
sealed class C1 : ISerializable
{
public C1()
{ }
private C1(SerializationInfo info, StreamingContext context)
{
field = (String)info.GetValue("field", typeof(String));
}
public void GetObjectData(SerializationInfo info,
StreamingContext context)
{
info.AddValue("field", field, typeof(String));
}
private String field;
}
Note. This diagnostic has an additional parameter, which can be configured in the configuration file (*.pvsconfig). It has the following syntax:
//+V3094:CONF:{ IncludeBaseTypes: true }
With this parameter on, the analyzer examines not only how the 'ISerializable' interface is implemented by the class itself, but also how it is implemented by any of the base classes. This option is off by default.
To learn more about configuration files, see this page.