Avoid prefixing type name with parent namespace name

Rule ND2013 Naming Conventions

Warns when the parent namespace name prefixes a contained type name (e.g. "RuntimeEnvironment" in namespace "Foo.Runtime" should be "Environment"): redundant naming without readability improvement. Types are not matched when several of them would end up with the same name once the prefix is removed (e.g. "MetricInfo" and "QualityGateInfo" both becoming "Info"). This rule doesn't warn about situations where two or more types end up with the same name.

How to fix

Remove the prefix from the type name.

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 prefixing type name with parent namespace name</Name>
// <Id>ND2013:AvoidPrefixingTypeNameWithParentNamespaceName</Id>

warnif count > 0

// Candidate types whose name starts with the parent namespace
// name, followed by an upper-case letter. This way we avoid
// matching false-positive where namespace name is "Stat" and
// type name is "Statistic".
let candidates = (
   from t in JustMyCode.Types
   where !t.IsNested &&
         !t.IsGeneratedByCompiler
   let ns = t.ParentNamespace.SimpleName
   where ns.Length > 0 &&
         t.Name.Length > ns.Length &&
         char.IsUpper(t.Name[ns.Length]) &&
         t.Name.StartsWith(ns)
   select new {
      t,
      namespaceName = ns,
      suffix = t.Name.Substring(ns.Length)
   }
).ToArray()

// Suffixes shared by several candidate types. Removing the
// prefix from all of them would end up with several types
// sharing the same name (e.g. MetricInfo and QualityGateInfo
// would both become Info). Don't warn in this situation.
let ambiguousSuffixes = candidates
   .GroupBy(c => c.suffix)
   .Where(g => g.Count() > 1)
   .Select(g => g.Key)
   .ToHashSetEx()

from c in candidates
where !ambiguousSuffixes.Contains(c.suffix)
select new {
   c.t,
   c.namespaceName,
   Debt = 10.ToMinutes().ToDebt(),
   Severity = Severity.Medium
}

//<Expl>
// The *{0}'s name* starts with the parent namespace name *{1}*.
// This results in redundant naming without any improvement in
// readability.
//</Expl>

//<Desc>
// Warns when the parent namespace name prefixes a contained type
// name (e.g. "RuntimeEnvironment" in namespace "Foo.Runtime"
// should be "Environment"): redundant naming without readability
// improvement. Types are not matched when several of them would
// end up with the same name once the prefix is removed (e.g.
// "MetricInfo" and "QualityGateInfo" both becoming "Info").
// This rule doesn't warn about situations where two or more 
// types end up with the same name.
//</Desc>

//<HowToFix>
// Remove the prefix from the type name.
//</HowToFix>

Naming Conventions: all 23 items