A field must not be assigned from outside its parent hierarchy types
Related to Fields should be declared as private: matches public or internal, mutable fields assigned from outside their parent class and subclasses. Fields are implementation details and should be private.
When a non-private field misbehaves, the culprit can be anywhere; a private field can only be assigned from its own class, usually one source file to look at.
When a non-private field misbehaves, the culprit can be anywhere; a private field can only be assigned from its own class, usually one source file to look at.
How to fix
Declare matched fields protected or better private. A field exclusively referencing immutable states can stay accessible but must be declared readonly.
Estimated Debt: 5 minutes per method outside the parent hierarchy assigning the field.
Estimated Debt: 5 minutes per method outside the parent hierarchy assigning the 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>A field must not be assigned from outside its parent hierarchy types</Name>
// <Id>ND1905:AFieldMustNotBeAssignedFromOutsideItsParentHierarchyTypes</Id>
warnif count > 0
from f in JustMyCode.Fields.Where(f =>
(f.IsInternal || f.IsPublic) &&
!f.IsGeneratedByCompiler &&
!f.IsImmutable &&
!f.IsEnumValue)
let methodsAssignerOutsideOfMyType = f.MethodsAssigningMe.Where(
m =>!m.IsGeneratedByCompiler &&
m.ParentType != f.ParentType &&
!m.ParentType.DeriveFrom(f.ParentType) )
where methodsAssignerOutsideOfMyType.Any()
select new {
f,
methodsAssignerOutsideOfMyType,
Debt = (5*methodsAssignerOutsideOfMyType.Count()).ToMinutes().ToDebt(),
Severity = Severity.High
}
//<Expl>
// The *{0}* is assigned outside its parent type by the *{1}*.
// A field should be an encapsulated *implementation detail*.
// Consider making it *private* or refactor it as a property
// whose accesses can be better controlled at debug-time.
//</Expl>
//<Desc>
// Related to *Fields should be declared as private*: matches **public or
// internal, mutable fields** assigned from outside their parent class and
// subclasses. Fields are **implementation details** and should be private.
//
// When a *non-private field* misbehaves, the culprit can be anywhere; a
// private field can only be assigned from its own class, usually one source
// file to look at.
//</Desc>
//<HowToFix>
// Declare matched fields *protected* or better *private*. A field
// exclusively referencing immutable states can stay accessible but must be
// declared readonly.
//
// Estimated Debt: 5 minutes per method outside the parent hierarchy
// assigning the 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