Gendarme's rules that check for serialization issues are located in the Gendarme.Rules.Serialization.dll assembly. Latest sources are available from anonymous SVN (http://anonsvn.mono-project.com/viewcvs/trunk/mono-tools/gendarme/rules/Gendarme.Rules.Serialization/).
Table of Contents
1.1 CallBaseMethodsOnISerializableTypesRule
1.2 DeserializeOptionalFieldRule
1.3 ImplementISerializableCorrectlyRule
1.4 MarkAllNonSerializableFieldsRule
1.5 MissingSerializableAttributeOnISerializableTypeRule
1.6 MissingSerializationConstructorRule
1.7 UseCorrectSignatureForSerializationMethodsRule
Rules
CallBaseMethodsOnISerializableTypesRule
This rule checks types that implement the System.ISerializable interface and report if either the serialization constructor or the GetObjectDatamethod does not call it's base type, potentially breaking the serialization process.
Bad example:
[Serializable] public class Base : ISerializable { // ... } [Serializable] public class Bad : Base { int value; protected BadDerived (SerializationInfo info, StreamingContext context) { value = info.GetInt32 ("value"); } public override void GetObjectData (SerializationInfo info, StreamingContext context) { info.AddValue ("value", value); } }
Good example:
[Serializable] public class Base : ISerializable { // ... } [Serializable] public class Good : Base { int value; protected BadDerived (SerializationInfo info, StreamingContext context) : base (info, context) { value = info.GetInt32 ("value"); } public override void GetObjectData (SerializationInfo info, StreamingContext context) { info.AddValue ("value", value); base.GetObjectData (info, context); } }
Notes
- This rule is available since Gendarme 2.2
DeserializeOptionalFieldRule
This rule checks for types that have field(s) marked with [OptionalField]. Such types should take care of re-computing the value(s) when the data is deserialized using the [OnDeserialized] or [OnDeserializing] attributes on a method. This rule only applies to assemblies compiled with the .NET framework version 2.0 (or later).
Bad example:
[Serializable] public class ClassWithOptionalField { [OptionalField] private int optional; }
Good example:
[Serializable] public class ClassWithOptionalField { [OptionalField] private int optional = 1; [OnDeserialized] private void Deserialized (StreamingContext context) { optional = 0; } [OnDeserializing] private void OnDeserializing (StreamingContext context) { optional = 0; } }
Notes
- This rule is available since Gendarme 2.0
ImplementISerializableCorrectlyRule
This rule checks for types that implements ISerializable. Such types are reponsible to serialize their data by implementing GetObjectData. This rule checks that every instance fields, not decorated with the [NonSerialized]attribute are serialized by the GetObjectData method. This rule will also warn if the type is unsealed and the GetObjectData is not virtual.
Bad example:
[Serializable] public class Bad : ISerializable { int foo; string bar; protected Bad (SerializationInfo info, StreamingContext context) { foo = info.GetInt32 ("foo"); } // extensibility is limited since GetObjectData is not virtual, // any type inheriting won't be able to serialized additional fields public void GetObjectData (SerializationInfo info, StreamingContext context) { info.AddValue ("foo", foo); // 'bar' is not serialized, if not needed then the field should // be decorated with [NotSerialized] } }
Good example (virtual and not serialized):
[Serializable] public class Good : ISerializable { int foo; [NotSerialized] string bar; protected Good (SerializationInfo info, StreamingContext context) { foo = info.GetInt32 ("foo"); } public virtual void GetObjectData (SerializationInfo info, StreamingContext context) { info.AddValue ("foo", foo); } }
Good example (sealed type and serialized):
[Serializable] public sealed class Good : ISerializable { int foo; string bar; protected Good (SerializationInfo info, StreamingContext context) { foo = info.GetInt32 ("foo"); } public void GetObjectData (SerializationInfo info, StreamingContext context) { info.AddValue ("foo", foo); info.AddValue ("bar", bar); } }
Notes
- This rule is available since Gendarme 2.0
MarkAllNonSerializableFieldsRule
This rule checks for serializable types, i.e. decorated with the [Serializable]attribute, and looks if all its fields are serializable too. If not the rule will warn unless the field itself is decorated with the [NonSerialized] attribute. The rule will also warn if the field type is an interface as it is not possible, before execution time, to know for certain if the type can be serialized or not.
Bad example:
class NonSerializableClass { } [Serializable] class SerializableClass { NonSerializableClass field; }
Good example:
class NonSerializableClass { } [Serializable] class SerializableClass { [NonSerialized] NonSerializableClass field; }
Notes
- This rule is available since Gendarme 2.0
MissingSerializableAttributeOnISerializableTypeRule
This rule checks for types that implements System.ISerializable but are not decorated with the [Serializable] attribute. Implementing System.ISerializable is not enough to make a class serializable as this interface only gives you more control over the basic serialization process. In order for the runtime to know your type is serializable it must have the [Serializable] pseudo-attribute.
Bad example:
// this type cannot be serialized by the runtime public class Bad : ISerializable { }
Good example:
[Serializable] public class Good : ISerializable { }
Notes
- This rule is available since Gendarme 2.0
MissingSerializationConstructorRule
This rule checks for types that implements System.ISerializable provide a serialization constructor, since the interface alone cannot force its presence. The serialization constructor should be private for sealed type, otherwise it should be protected.
Bad example:
[Serializable] public class Bad : ISerializable { public void GetObjectData (SerializationInfo info, StreamingContext context) { } }
Good example (sealed):
[Serializable] public sealed class Good : ISerializable { private ClassWithConstructor (SerializationInfo info, StreamingContext context) { } public void GetObjectData (SerializationInfo info, StreamingContext context) { } }
Good example:
[Serializable] public class Good : ISerializable { protected ClassWithConstructor (SerializationInfo info, StreamingContext context) { } public void GetObjectData (SerializationInfo info, StreamingContext context) { } }
Notes
- This rule is available since Gendarme 2.0
UseCorrectSignatureForSerializationMethodsRule
This rule checks for methods using the special serialization attributes, [OnSerializing, OnDeserializing, OnSerialized, OnDeserialized]. You must ensure that the methods have the correct signature. They should be private, return void and have a single parameter of type StreamingContext. Failure to have the right signature can, in some circumstances, make your assembly unusable at runtime.
Bad example:
[Serializable] public class Bad { [OnSerializing] public bool Serializing (StreamingContext context) { } }
Good example:
[Serializable] public class BadClass { [OnSerializing] private void Serializing (StreamingContext context) { } }
Notes
- This rule is available since Gendarme 2.0
Feedback
Please report any documentation errors, typos or suggestions to the Gendarme Google Group (http://groups.google.com/group/gendarme). Thanks!



