Gendarme.Rules.Naming

Gendarme's naming rules are located in the Gendarme.Rules.Naming.dll assembly. Latest sources are available from anonymous SVN (http://anonsvn.mono-project.com/viewcvs/trunk/mono-tools/gendarme/rules/Gendarme.Rules.Naming/).

Rules

AvoidDeepNamespaceHierarchyRule

This rule check the depth of the namespace declared inside an assembly. It will warn if the depth is greater then four (default value) unless the fifth (or the next) part is one of the specialized name that the framework recommands or an named like an internal namespace (something not meant to be seen outside the assembly).

  • Design : Namespace that provides design-time support for its base namespace.
  • Interop : Namespace that provides all interoperability code (e.g. p./invokes) for its base namespace.
  • Permissions : Namespace that provides all custom permissions for its base namespace.
  • Internal : Namespace that provides non visible (outside the assembly) helper code for its base namespace. Impl while allowed by the rule is not encouraged.


Bad example:

namespace One.Two.Three.Four.Five {
    internal class Helper {
    }
}

Good example:

namespace One.Two.Three.Four {
    internal class FiveHelper {
    }
}

Good example (exception for some namespace specialization):

namespace One.Two.Three.Four.Internal {
    internal class Helper {
    }
}

AvoidNonAlphanumericIdentifierRule

This rule ensures that identifiers like assembly names, namespaces, types and members names don't have any non-alphanumerical characters inside them. The rule will ignore interfaces used for COM interoperability - i.e. decorated with both [InterfaceType] and [Guid] attributes.

Bad example:

namespace New_Namespace {
    
    public class My_Custom_Class {
        
        public int My_Field;
        
        public void My_Method (string my_string)
        {
        }
    }
}

Good example:

namespace NewNamespace {
    
    public class MyCustomClass {
        
        public int MyField;
        
        public void MyMethod (string myString)
        {
        }
    }
}

Notes

  • Prior to Gendarme 2.2 this rule was named DetectNonAlphanumericInTypeNamesRule

AvoidRedundancyInMethodNameRule

This rule checks if a method is named against its first parameter's type. Usually, removing that type name from the method name makes an API less verbose, easier to learn, and more future-proof.

Bad example:

class PostOffice {
    public void SendLetter (Letter letter) {
    }
    public void SendPackage (Package package) {
    }
}

Good example:

class PostOffice {
    public void Send (Letter letter) {
    }
    public void Send (Package package) {
    }
}

Bad example:

class PostOffice {
    public static bool IsPackageValid (Package package) {
        return package.HasAddress && package.HasStamp;
    }
}

Good example:

class Package {
    public bool IsValid {
        get {
            return HasAddress && HasStamp;
        }
    }
}

AvoidRedundancyInTypeNameRule

This rule checks if a type is prefixed with the last component of its enclosing namespace, and that removing the prefix would not cause undesirable ambiguity with its base type or a type from a parent namespace. If possible, removing the prefix from the type name usually makes an API less verbose and more autocompletion-friendly.

Bad example:

namespace Foo.Lang.Compiler {
    public class CompilerContext {
    }
}
using Foo.Lang;
...
Compiler.CompilerContext context = new Compiler.CompilerContext ();
using Foo.Lang.Compiler;
...
CompilerContext context = new CompilerContext ();

Good example:

namespace Foo.Lang.Compiler {
    public class Context {
    }
}
using Foo.Lang;
...
Compiler.Context context = new Compiler.Context ();
using Foo.Lang.Compiler;
...
Context context = new Context ();

Another good example (more meaningful term in the context of the namespace):

namespace Foo.Lang.Compiler {
    public class CompilationContext {
    }
}

AvoidTypeInterfaceInconsistencyRule

This rule checks for inconsistencies between interfaces and types names that are part of the same namespace and assembly. If an interface and a type names differs only by the I prefix (of the interface) then we can logically expect the type to implement this interface.

Bad example:

public interface IMember {
    string Name {
        get;
    }
}
 
public class Member {
    public string Name {
        get {
            return String.Empty;
        }
    }
}

Good example:

public interface IMember {
    string Name {
        get;
    }
}
 
public class Member : IMember {
    public string Name {
        get {
            return String.Empty;
        }
    }
}

Notes

  • This rule is available since Gendarme 2.4

DoNotPrefixEventsWithAfterOrBeforeRule

This rule ensures event names are not prefixed with After or Before. The .NET naming convention suggest to name them using a verb in the present and in the past tense.

Bad example:

public class Bad {
    public event ResolveEventHandler BeforeResolve;
    public event ResolveEventHandler AfterResolve;
}

Good example:

public class Good {
    public event ResolveEventHandler Resolving;	// present
    public event ResolveEventHandler Resolved;	// past
}

DoNotPrefixValuesWithEnumNameRule

This rule checks for enum values that are prefixed with the enumeration type name. This is typical in C/C++ application but unneeded in .NET since the enum type name must be specified anyway when used.

Bad example:

public enum Answer {
    AnswerYes,
    AnswerNo,
    AnswerMaybe,
}

Good example:

public enum Answer {
    Yes,
    No,
    Maybe
}

DoNotUseReservedInEnumValueNamesRule

This rule checks for enumerations that contains values named reserved. This practice, often seen in C/C++ application, is not needed in .NET since adding new values is not a breaking change. However renaming a reserved value to a new name would be a breaking change.

Bad example:

public enum Answer {
    Yes,
    No,
    Reserved
    // ^ renaming this to 'Maybe' would be a breaking change
}

Good example:

public enum Answer {
    Yes,
    No
    // we can add Maybe anytime without causing a breaking change
}

ParameterNamesShouldMatchOverriddenMethodRule

This rule warns if an overriden method's parameter names do not match those of the base class or those of the implemented interface.

Bad example:

public class Base {
    public abstract void Write (string text);
}
 
public class SubType : Base {
    public override void Write (string output)
    {
        //...
    }
}

Good example:

public class Base {
    public abstract void Write (string text);
}
 
class SubType : Base {
    public override void Write (string text)
    {
        //...
    }
}

UseCorrectCasingRule

This rule ensure that identifier are correctly cased. In particular:

  • namespace names are pascal cased
  • type names are pascal cased
  • method names are pascal cased
  • parameter names are camel cased


Bad example:

namespace A {
    abstract public class myClass {
        abstract public int thisMethod (int ThatParameter);
    }
}

Good example:

namespace Company.Product.Technology {
    abstract public class MyClass {
        abstract public int ThisMethod (int thatParameter);
    }
}

UseCorrectPrefixRule

This rule ensure that types are prefixed correctly. Interfaces should always be prefixed with a I, types should never prefixed with a C (remainder for MFC folks) and generic parameters should be a single, uppercased letter or be prefixed with T.

Bad examples:

public interface Phone {
    // ...
}
 
public class CPhone : Phone {
    // ...
}
 
public class Call<Mechanism> {
    // ...
}

Good examples:

public interface IPhone {
    // ...
}
 
public class Phone : IPhone {
    // ...
}
 
public class Call<TMechanism> {
    // ...
}

UseCorrectSuffixRule

This rule ensure that types that inherit from certain types or implement some interfaces are named correctly by appending the right suffix to them. It also ensure that no other types are using the suffixes without inheriting/implementing the types/interfaces. E.g.

  • System.Attribute should end with Attribute
  • System.EventArgs should end with EventArgs
  • System.Exception should end with Exception
  • System.Collections.Queue should end with Collection or Queue
  • System.Collections.Stack should end with Collection or Stack
  • System.Data.DataSet should end with DataSet
  • System.Data.DataTable should end with DataTable or Collection
  • System.IO.Stream should end with Stream
  • System.Security.IPermission should end with Permission
  • System.Security.Policy.IMembershipCondition should end with Condition
  • System.Collections.IDictionary or System.Collections.Generic.IDictionary should end with Dictionary
  • System.Collections.ICollection, System.Collections.Generic.ICollection or System.Collections.IEnumerable should end with Collection


Bad example:

public sealed class SpecialCode : Attribute {
    // ...
}

Good example:

public sealed class SpecialCodeAttribute : Attribute {
    // ...
}

UsePluralNameInEnumFlagsRule

This rule ensure that the name of enumeration flags is in plural form.

Bad example:

[Flags]
public enum MyCustomValue {
    Foo,
    Bar,
    AllValues = Foo | Bar
}

Good example:

[Flags]
public enum MyCustomValues {
    Foo,
    Bar,
    AllValues = Foo | Bar
}

UsePreferredTermsRule

This rule ensure that identifiers such as assemblies, namespaces, types and members, use the terms suggested by the .NET framework guidelines to ensure uniformity across all class libraries.

  • Arent should be replaced with AreNot;
  • Cancelled should be replaced with Canceled;
  • Cant should be replaced with Cannot;
  • ComPlus should be replaced with EnterpriseServices;
  • Couldnt should be replaced with CouldNot;
  • Didnt should be replaced with DidNot;
  • Doesnt should be replaced with DoesNot;
  • Dont should be replaced with DoNot;
  • Hadnt should be replaced with HadNot;
  • Hasnt should be replaced with HasNot;
  • Havent should be replaced with HaveNot;
  • Indices should be replaced with Indexes;
  • Isnt should be replaced with IsNot;
  • LogIn should be replaced with LogOn;
  • LogOut should be replaced with LogOff;
  • Shouldnt should be replaced with ShouldNot;
  • SignOn should be replaced with SignIn;
  • SignOff should be replaced with SignOut;
  • Wasnt should be replaced with WasNot;
  • Werent should be replaced with WereNot;
  • Wont should be replaced with WillNot;
  • Wouldnt should be replaced with WouldNot;
  • Writeable should be replaced with Writable;


Bad example:

abstract public class ComPlusSecurity {
    abstract public void LogIn ();
    abstract public void LogOut ();
}

Good example:

abstract public class EnterpriseServicesSecurity {
    abstract public void LogOn ();
    abstract public void LogOff ();
}

UseSingularNameInEnumsUnlessAreFlagsRule

The rule is used for ensure that the name of enumerations are in singular form unless the enumeration is used as flags, i.e. decorated with the [Flags] attribute.

Bad example:

public enum MyCustomValues {
    Foo,
    Bar
}

Good example (singular):

public enum MyCustomValue {
    Foo,
    Bar
}

Good example (flags):

[Flags]
public enum MyCustomValues {
    Foo,
    Bar,
    AllValues = Foo | Bar
}

Feedback

Please report any documentation errors, typos or suggestions to the Gendarme Google Group (http://groups.google.com/group/gendarme). Thanks!