Types tagged with ImmutableAttribute must be immutable
A type is immutable if its instance fields are only assigned inline or from constructor(s). NDepend.Attributes.ImmutableAttribute (from NDepend.API.dll, or your own attribute, adapting the rule) expresses in code that a type is immutable; this rule continuously checks it and warns when a tagged type is no longer immutable.
How to fix
Find which modification broke immutability (the culpritFields list helps), then refactor the type back to immutability.
Estimated Debt: 5 minutes plus 10 minutes per culprit field.
Estimated Debt: 5 minutes plus 10 minutes per culprit field.
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>Types tagged with ImmutableAttribute must be immutable</Name>
// <Id>ND1909:TypesTaggedWithImmutableAttributeMustBeImmutable</Id>
warnif count > 0
from t in Application.Types where
t.HasAttribute ("NDepend.Attributes.ImmutableAttribute".AllowNoMatch()) &&
!t.IsImmutable
let culpritFields = t.Fields.Where(f => !f.IsStatic && !f.IsImmutable)
select new {
t,
culpritFields,
Debt = (5+10*culpritFields.Count()).ToMinutes().ToDebt(),
Severity = Severity.High
}
//<Expl>
// The *{0}* is tagged with the *ImmutableAttribute* yet it is mutable:
// its *{1}* can be assigned.
// This attribute indicates a commitment to keep this type immutable
// so make sure its instance states cannot be changed after construction.
//</Expl>
//<Desc>
// A type is immutable if its instance fields are only assigned inline or
// from constructor(s). **NDepend.Attributes.ImmutableAttribute** (from
// *NDepend.API.dll*, or your own attribute, adapting the rule) expresses in
// code that a type is immutable; this rule continuously checks it and warns
// when a tagged type is no longer immutable.
//</Desc>
//<HowToFix>
// Find which modification broke immutability (the *culpritFields* list
// helps), then refactor the type back to immutability.
//
// Estimated Debt: 5 minutes plus 10 minutes per culprit field.
//</HowToFix>
Open in the interactive Rules Explorer · All default rules
Immutability: all 15 items
- Fields should be marked as ReadOnly when possible ND1900
- Avoid non-readonly static fields ND1901
- Avoid static fields with a mutable field type ND1902
- Structures should be immutable ND1903
- Immutable struct should be declared as readonly ND1914
- Property Getters should be pure ND1904
- A field must not be assigned from outside its parent hierarchy types ND1905
- Don't assign a field from many methods ND1906
- Do not declare read only fields with mutable reference types ND1907
- Public read only array fields can be modified ND1908
- Types tagged with ImmutableAttribute must be immutable ND1909
- Types immutable should be tagged with ImmutableAttribute ND1910
- Methods tagged with PureAttribute must be pure ND1911
- Pure methods should be tagged with PureAttribute ND1912
- Record should be immutable ND1913