Fields should be marked as ReadOnly when possible
Warns about instance and static fields declarable as readonly, based on IField.IsImmutable: https://www.ndepend.com/api/NDepend.CodeModel.IField.html#NDepend_CodeModel_IField_IsImmutable An IsImmutable field is only assigned by constructors of its class: its value stays constant through the object lifetime (instance field) or the program lifetime (static field).
readonly enhances robustness and readability: it defines a contract that the field is not altered after initialization, and enforces it.
readonly enhances robustness and readability: it defines a contract that the field is not altered after initialization, and enforces it.
How to fix
Declare the field with the C# readonly keyword (ReadOnly in VB.NET).
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>Fields should be marked as ReadOnly when possible</Name>
// <Id>ND1900:FieldsShouldBeMarkedAsReadOnlyWhenPossible</Id>
warnif count > 0
from f in JustMyCode.Fields where
f.IsImmutable &&
!f.IsInitOnly && // The condition IsInitOnly matches fields that
// are marked with the C# readonly keyword
// (ReadOnly in VB.NET).
!f.IsGeneratedByCompiler &&
!f.IsEventDelegateObject &&
!f.ParentType.IsEnumeration &&
!f.IsLiteral &&
// Don't warn if a method using the field is also calling a method that has 'ref' and 'out' parameters.
// This could lead to false positive. A field used in a 'ref' or 'out' parameter cannot be set as read-only.
f.MethodsUsingMe.SelectMany(m => m.MethodsCalled).FirstOrDefault(m => m.Name.Contains("&")) == null &&
// Don't warn for fields tagged with these Unity specific attribute
!f.HasAttribute("UnityEngine.SerializeField".AllowNoMatch()) &&
!f.HasAttribute("UnityEngine.SerializeReference".AllowNoMatch()) &&
// Don't warn about InlineArrayAttribute's field
!f.ParentType.HasAttribute("System.Runtime.CompilerServices.InlineArrayAttribute".AllowNoMatch())
select new {
f,
f.MethodsReadingMeButNotAssigningMe,
f.MethodsAssigningMe,
Debt = 5.ToMinutes().ToDebt(),
Severity = Severity.Medium
}
//<Expl>
// The *{0}* can be declared as **readonly**.
// Doing so explicitly conveys that the field
// should not be altered after initialization
// and enforces this constraint.
//</Expl>
//<Desc>
// Warns about instance and static fields declarable as **readonly**, based
// on *IField.IsImmutable*:
// https://www.ndepend.com/api/NDepend.CodeModel.IField.html#NDepend_CodeModel_IField_IsImmutable
// An *IsImmutable* field is only assigned by constructors of its class: its
// value stays constant through the object lifetime (instance field) or the
// program lifetime (static field).
//
// *readonly* enhances robustness and readability: it defines a contract
// that the field is not altered after initialization, and enforces it.
//</Desc>
//<HowToFix>
// Declare the field with the C# *readonly* keyword (*ReadOnly* in VB.NET).
//</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