Avoid non-readonly static fields

Rule ND1901 Immutability

Warns about static fields not declared read-only. Instance fields are the natural OOP artifact for mutable state; mutable static fields create confusion about runtime state and impair testability (the same mutable state is re-used per test). More: https://blog.ndepend.com/the-proper-usages-of-the-keyword-static-in-c/

How to fix

If assigned once per program lifetime, declare the field readonly and assign it inline or in the static constructor. Otherwise refactor to hold the state in an instance 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>Avoid non-readonly static fields</Name>
// <Id>ND1901:AvoidNonReadOnlyStaticFields</Id>

warnif count > 0
from f in JustMyCode.Fields
where f.IsStatic && 
     !f.IsEnumValue && 
     !f.IsGeneratedByCompiler &&
     !f.IsLiteral &&
     !f.IsInitOnly

let methodAssigningField = f.MethodsAssigningMe

select new { 
   f, 
   methodAssigningField,
   Debt = (2+8*methodAssigningField.Count()).ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Expl>
// The *static {0}* should be declared as *readonly* because changing it can lead to runtime confusion and hinder code testability.
// In *Object-Oriented Programming*, *instance fields* are the preferred choice for holding modifiable states.
//</Expl>

//<Desc>
// Warns about static fields not declared read-only. **Instance fields** are
// the natural OOP artifact for mutable state; mutable static fields create
// *confusion* about runtime state and impair testability (the same mutable
// state is re-used per test). More:
// https://blog.ndepend.com/the-proper-usages-of-the-keyword-static-in-c/
//</Desc>

//<HowToFix>
// If assigned once per program lifetime, declare the field *readonly* and
// assign it inline or in the static constructor. Otherwise refactor to hold
// the state in an instance field.
//</HowToFix>

Immutability: all 15 items