Broken serializable types
Runs only in diff mode (baseline defined). Warns about types tagged SerializableAttribute whose serializable instance fields were added or removed (fields tagged NonSerializedAttribute are ignored).
From http://msdn.microsoft.com/library/system.serializableattribute.aspx : all fields of a SerializableAttribute type are serialized by default, unless the type implements ISerializable or fields are marked NonSerializedAttribute.
From http://msdn.microsoft.com/library/system.serializableattribute.aspx : all fields of a SerializableAttribute type are serialized by default, unless the type implements ISerializable or fields are marked NonSerializedAttribute.
How to fix
Keep the serialization process of serializable types stable, now and in the future; else deal with Version Tolerant Serialization: https://msdn.microsoft.com/en-us/library/ms229752(v=vs.110).aspx
Severity is High: an API Breaking change can provoke significant friction with API consumers.
Severity is High: an API Breaking change can provoke significant friction with API consumers.
CQLinq source
This rule is written in CQLinq, C# LINQ over the NDepend code model. It ships with every new NDepend project: you can read it, adapt it, or use it as a starting point for your own custom rules.
// <Name>Broken serializable types</Name>
// <Id>ND1504:BrokenSerializableTypes</Id>
warnif count > 0
from t in Application.Types where
// Collect types tagged with SerializableAttribute
t.HasAttribute("System.SerializableAttribute".AllowNoMatch()) &&
!t.IsDelegate &&
t.IsPresentInBothBuilds()
// Find newer and older versions of NonSerializedAttribute
let newNonSerializedAttribute = ThirdParty.Types.WithFullName("System.NonSerializedAttribute").SingleOrDefault()
let oldNonSerializedAttribute = newNonSerializedAttribute == null ? null : newNonSerializedAttribute.OlderVersion()
// Find added or removed fields not marked with NonSerializedAttribute
let addedInstanceField = from f in t.InstanceFields where
f.WasAdded() &&
(newNonSerializedAttribute == null || !f.HasAttribute(newNonSerializedAttribute))
select f
let removedInstanceField = from f in t.OlderVersion().InstanceFields where
f.WasRemoved() &&
(oldNonSerializedAttribute == null || !f.HasAttribute(oldNonSerializedAttribute))
select f
where addedInstanceField.Count() > 0 || removedInstanceField.Count() > 0
select new {
t,
addedInstanceField,
removedInstanceField,
Debt = 20.ToMinutes().ToDebt(),
Severity = Severity.Critical
}
//<Expl>
// The field set of the serializable *{0}* changed since the baseline.
// This can break client code using it.
// New field{1?:s}: *{1}* Removed field{2?:s}: *{2}*
//</Expl>
//<Desc>
// Runs only in *diff mode* (baseline defined). Warns about types tagged
// *SerializableAttribute* whose serializable instance fields were added or
// removed (fields tagged *NonSerializedAttribute* are ignored).
//
// From http://msdn.microsoft.com/library/system.serializableattribute.aspx :
// all fields of a *SerializableAttribute* type are serialized by default,
// unless the type implements *ISerializable* or fields are marked
// *NonSerializedAttribute*.
//</Desc>
//<HowToFix>
// Keep the serialization process of serializable types stable, now and in
// the future; else deal with **Version Tolerant Serialization**:
// https://msdn.microsoft.com/en-us/library/ms229752(v=vs.110).aspx
//
// Severity is **High**: an API Breaking change can provoke significant
// friction with API consumers.
//</HowToFix>
Open in the interactive Rules Explorer · All default rules
API Breaking Changes: all 9 items
- API Breaking Changes: Types ND1500
- API Breaking Changes: Methods ND1501
- API Breaking Changes: Fields ND1502
- API Breaking Changes: Interfaces and Abstract Classes ND1503
- Broken serializable types ND1504
- Avoid changing enumerations Flags status ND1505
- API: New publicly visible types
- API: New publicly visible methods
- API: New publicly visible fields