Created
May 13, 2013 15:53
-
-
Save anonymous/5569350 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// <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