Instance fields naming convention

Rule ND2000 Naming Conventions

Supports the 3 most used instance field naming conventions (adaptable to your own):

- name starting with a lower-case letter

- name starting with "_" followed by a lower-case letter

- name starting with "m_" followed by an upper-case letter

A static field behaves completely differently from an instance field, so differentiating them at a glance (e.g. m_ prefix) is valuable. Related discussion: https://blog.ndepend.com/on-hungarian-notation-for-fields-in-csharp/

How to fix

After adapting the rule to your naming convention, name all matched instance fields adequately.

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>Instance fields naming convention</Name>
// <Id>ND2000:InstanceFieldsNamingConvention</Id>

warnif count > 0 
let isUnityProject = ThirdParty.Assemblies.Any(a => a.Name.StartsWith("UnityEngine"))
from f in JustMyCode.Fields where 
  !f.IsStatic && 
  !f.IsLiteral && 
  !f.IsGeneratedByCompiler  && 
  !f.IsSpecialName && 
  !f.IsEventDelegateObject &&
  !( 
    // Instance field name starting with a lower-case letter
    (f.Name.Length >= 1 && char.IsLetter(f.Name[0]) && char.IsLower(f.Name[0])) ||

    // Instance field name starting with "_" followed with a lower-case letter
    (f.Name.Length >= 2 && f.Name.StartsWith("_") && char.IsLetter(f.Name[1]) && char.IsLower(f.Name[1])) ||

    // Instance field name starting with "m_" followed with an upper-case letter
    (f.Name.Length >= 3 && f.Name.StartsWith("m_") && char.IsLetter(f.Name[2]) && char.IsUpper(f.Name[2])) ||

    // In Unity projects often there is no properties for high-performance reasons and fields are named like properties.
    (isUnityProject && char.IsLetter(f.Name[0]) && char.IsUpper(f.Name[0]))

  ) &&
   // Don't check naming convention on serializable fields
  !f.HasAttribute("System.Xml.Serialization.XmlAttributeAttribute".AllowNoMatch()) &&
  !f.HasAttribute("System.Runtime.Serialization.DataMemberAttribute".AllowNoMatch()) &&
  
   // 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 
  
select new {
   f,
   f.SizeOfInst,
   Debt = 3.ToMinutes().ToDebt(),
   Severity = Severity.Medium
} 

//<Expl>
// The *instance {0}* name does not adhere to usual .NET field naming conventions.
// It does not start with a lowercase letter, 
// an underscore character followed by a lowercase letter 
// or an *m_* expression followed by an uppercase letter.
//</Expl>

//<Desc>
// Supports the 3 most used instance field naming conventions (adaptable to
// your own):
//
// - name starting with a lower-case letter
//
// - name starting with "_" followed by a lower-case letter
//
// - name starting with "m_" followed by an upper-case letter
//
// A *static field* behaves completely differently from an *instance field*,
// so differentiating them at a glance (e.g. **m_** prefix) is valuable.
// Related discussion:
// https://blog.ndepend.com/on-hungarian-notation-for-fields-in-csharp/
//</Desc>

//<HowToFix>
// After adapting the rule to your naming convention, name all matched
// instance fields adequately.
//</HowToFix>

Naming Conventions: all 23 items