Don't assign static fields from instance methods

Rule ND1211 Object Oriented Design

Assigning static fields from instance methods leads to poorly maintainable and non-thread-safe code. More discussion: https://blog.ndepend.com/the-proper-usages-of-the-keyword-static-in-c/

How to fix

If the static field is assigned once per program lifetime, declare it readonly and assign it inline or in the static constructor. Otherwise hold mutable state in instance fields, the natural OOP artifact for it.

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>Don't assign static fields from instance methods</Name>
// <Id>ND1211:DontAssignStaticFieldsFromInstanceMethods</Id>
warnif count > 0
from f in JustMyCode.Fields where 
  f.IsStatic &&
 !f.IsLiteral &&
 !f.IsInitOnly &&
 !f.IsGeneratedByCompiler &&
  // Contract API define such a insideContractEvaluation static field
  f.Name != "insideContractEvaluation"
let assignedBy = f.MethodsAssigningMe.Where(m => !m.IsStatic)
where assignedBy .Count() > 0
select new { 
   f, 
   assignedBy,
   Debt = 5.ToMinutes().ToDebt(),
   Severity = Severity.Medium
}

//<Expl>
// The *{0}* is assigned from {1?this:these} instance 
// method{1?:s}: *{1}*. This can lead to unexpected *side effects*
// since all instances are sharing the same state.
//</Expl>
     
//<Desc>
// Assigning static fields from instance methods leads to poorly
// maintainable and non-thread-safe code. More discussion:
// https://blog.ndepend.com/the-proper-usages-of-the-keyword-static-in-c/
//</Desc>

//<HowToFix>
// If the *static* field is assigned once per program lifetime, declare it
// *readonly* and assign it inline or in the static constructor. Otherwise
// hold mutable state in **instance fields**, the natural OOP artifact for it.
//</HowToFix>

Object Oriented Design: all 14 items