Avoid fields with same name in class hierarchy
Matches a field whose name is already used in the base class hierarchy. Compilers allow it (even when the base field is visible to derived classes), but it is likely an erroneous attempt to redefine a field.
How to fix
If the derived field is indeed a redefinition (same field type; for statics, a single instance suffices), delete it and make the base field protected. Otherwise rename the derived field, carefully renaming all its usages (they might relate to the base 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>Avoid fields with same name in class hierarchy</Name>
// <Id>ND2019:AvoidFieldsWithSameNameInClassHierarchy</Id>
warnif count > 0
// Optimization: only consider fields of derived classes
let derivedClasses = Application.Types.Where(t =>
t.IsClass &&
!t.IsStatic &&
t.DepthOfInheritance > 1 &&
t.BaseClasses.ChildFields().Any())
from f in derivedClasses.ChildFields()
where JustMyCode.Contains(f) // Make sure it is fixable by targeting only JustMyCode fields
let fieldsOfBaseClassesWithSameName =
f.ParentType
.BaseClasses
.ChildFields()
.Where(cf => cf.Name == f.Name && JustMyCode.Contains(cf))
where fieldsOfBaseClassesWithSameName.Any()
select new {
f,
fieldsOfBaseClassesWithSameName,
baseClasses = fieldsOfBaseClassesWithSameName.Select(f1 => f1.ParentType).ToArray(),
Debt = 10.ToMinutes().ToDebt(),
Severity = Severity.Medium
}
//<Expl>
// There {2?is:are} {2?a:} field{2?:s} with same name as *{0}* in the base class{2?:es}: *{2}*.
// Investigate this ambiguous situation. It might reveal an incorrect attempt to redeclare a field in a derived class.
//</Expl>
//<Desc>
// Matches a field whose name is already used in the base class hierarchy.
// Compilers allow it (even when the base field is visible to derived
// classes), but it is likely an erroneous attempt to redefine a field.
//</Desc>
//<HowToFix>
// If the derived field is indeed a redefinition (same field type; for
// statics, a single instance suffices), delete it and make the base field
// *protected*. Otherwise rename the derived field, carefully renaming all
// its usages (they might relate to the base field).
//</HowToFix>
Open in the interactive Rules Explorer · All default rules
Naming Conventions: all 23 items
- Instance fields naming convention ND2000
- Static fields naming convention ND2001
- Interface name should begin with a 'I' ND2002
- Abstract base class should be suffixed with 'Base' ND2003
- Exception class name should be suffixed with 'Exception' ND2004
- Attribute class name should be suffixed with 'Attribute' ND2005
- Types name should begin with an Upper character ND2006
- Methods name should begin with an Upper character ND2007
- Do not name enum values 'Reserved' ND2008
- Avoid types with name too long ND2009
- Avoid methods with name too long ND2010
- Avoid fields with name too long ND2011
- Avoid having different types with same name ND2012
- Avoid prefixing type name with parent namespace name ND2013
- Avoid naming types and namespaces with the same identifier ND2014
- Don't call your method Dispose ND2015
- Methods prefixed with 'Try' should return a boolean ND2016
- Properties and fields that represent a collection of items should be named Items. ND2017
- DDD ubiquitous language check ND2018
- Avoid fields with same name in class hierarchy ND2019
- Avoid various capitalizations for method name ND2020
- Controller class name should be suffixed with 'Controller' ND2021
- Nested class members should not mask outer class' static members ND2022