Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/5569350 to your computer and use it in GitHub Desktop.
Save anonymous/5569350 to your computer and use it in GitHub Desktop.
// <Name>Don't assign a field from many methods</Name>
warnif count > 0
from f in JustMyCode.Fields where
!f.IsEnumValue &&
!f.IsImmutable &&
!f.IsInitOnly &&
!f.IsGeneratedByCompiler &&
!f.IsEventDelegateObject &&
(f.IsPrivate || f.IsProtected) // Don't match fields assigned outside their classes.
// The threshold 4 is arbitrary and it should avoid matching too many fields.
// Threshold is even lower for static fields because this reveals situations even more complex.
where f.MethodsAssigningMe.Count() >= (!f.IsStatic ? 4 : 2)
select new { f,
f.MethodsAssigningMe,
f.MethodsReadingMeButNotAssigningMe,
f.MethodsUsingMe,
f.ParentType }
// A field assigned from many methods is a symptom of bug-prone code.
// This situation makes harder to anticipate the field state during runtime.
// The code is then hard to read, hard to debug and hard to maintain.
// Hard-to-solve bugs due to corrupted state are often the consequence of fields anarchically assigned.
//
// The situation is even more complex if the field is static.
// Indeed, this potentially involves global random accesses from different parts of the application.
// This is why this rule provides a lower threshold for static fields.
//
// If the object containing such field is meant to be used from multiple threads,
// there are alarming chances that the code is unmaintainable and bugged.
// When multiple threads are involved, the rule of thumb is to use immutable objects.
//
// If the field type is a reference type (interfaces, classes, strings, delegates)
// corrupted state might result in a NullReferenceException.
// If the field type is a value type (number, boolean, structure)
// corrupted state might result in wrong result not even signaled by an exception sent.
//
// There is no straight advice to refactor the number of methods responsible for assigning a field.
// Solutions often involve rethinking and then rewriting a complex algorithm.
// Such field can sometime become just a variable accessed locally by a method or a closure.
// Sometime, just rethinking the life-time and the role of the parent object allows the field to become immutable
// (i.e assigned only by the constructor).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment