Naming Conventions

Identifiers

DO follow the these rules about capitalization when naming identifiers:

Identifier Casing Example
Namespace Pascal namespace System.Security { ... }
Type Pascal public class StreamReader { ... }
Interface Pascal public interface IEnumerable { ... }
Method Pascal public virtual string ToString() { ... }
Property Pascal public string Name { get { ... } }
Event Pascal public event EventHandler Exited;
Public Field Pascal public static readonly TimeSpan InfiniteTimeout;
Public Const Pascal public const Min = 0;
Private Field Camel private string url;
Enum Value Pascal public enum FileMode { Append, ... }
Parameter Camel public static int ToInt32(string value);

Rules for Compound Words

DO follow these examples about compound words:

Pascal Camel Not
BitFlag bitFlag Bitflag
Callback [1] Callback CallBack
Canceled Canceled Cancelled
DoNot doNot Don’t
Email Email EMail
Endpoint [1] Endpoint EndPoint
FileName filename Filename
Gridline [1] Gridline GridLine
Hashtable [1] Hashtable HashTable
Id id ID
Indexes indexes Indices
LogOff logOff LogOut
LogOn logOn LogIn
Metadata [1] metadata MetaData
Multipanel [1] multipanel MultiPanel
Multiview [1] multiview MultiView
Namespace [1] namespace NameSpace
Ok ok OK
Pi pi PI
Placeholder placeholder PlaceHolder
SignIn signIn SignOn
SignOut signOut SignOff
UserName userName Username
WhiteSpace whiteSpace Whitespace
Writable writable Writeable

Footnotes

[1](1, 2, 3, 4, 5, 6, 7, 8) These are what are called closed-form compound words and should be treated as a single word. If you would write it as a single word in a sentence, do so in an identifier as well.

Case Sensitivity

DO NOT vary identifiers based solely on capitalization. The CLR in general does not require that identifiers vary based on sensitivity (Age is the same as age). C# does support it (as it is a C type language), but the only time it is acceptable to do so is in field backed properties, as follows:

class Person {
    private int age;

    public int Age {
        return age;
    }
}

General Naming Conventions

This section describes general naming conventions that relate to word choice, guidelines on using abbreviations and acronyms, and recommendations on how to avoid using language-specific names.

Word choice

DO choose easily readable, descriptive names. HorizontalAlignment rather than AlignmentHorizontal.

DO favour readability over brevity. CanScrollHorizontally rather than ScrollableX.

DO NOT use underscores, hyphens, or any other non-alphanumeric characters.

DO NOT use Hungarian notation. Cost should be cost not dCost (where the “d” would indicate that its decimal).

AVOID naming variables the same as language keywords. You should not have an identifier called private as that is a reserved word. Most languages won’t allow it anyways. In C#, however, you can prefix a name with a “commercial at” (@) to escape reserved words. Avoid this except in cases where it doesn’t make sense. Example: @class is preferable to clazz in code dealing with CSS generation.

Abbreviations and Acronyms

DO NOT use abbreviations and/or acronyms as part of identifier names. GetWindow not GetWin. The most obvious places where this might need to be violated is dealing with 3rd party REST APIs. But in those cases there are override mechanisms available in the JSON and XML serialization mechanisms to override naming. Example:

public class Screen {
    [XmlAttribute(“Win”)]
    public string Window { get; set; }
}

Sometimes, based on business rules, it might be appropriate to utilize acronyms. But this, again, is only when part of an API and is in the public contract of the API (internal code should strive to avoid use of the acronyms).

Avoid Language Specific Names

DO use semantically interesting names rather than language-specific keywords for type names. Use GetLength not GetInt.

DO use generic CLR type names, rather than language specific ones, in the rare cases when an identifier has no semantic meaning beyond its type. Given a class called Convert, the method would be ToInt64 not ToLong as long is the C# keyword for the underlying CLR type Int64. So when naming methods that need to include a type name:

Use this, instead of: C# Visual Basic C++
SByte sbyte SByte char
Byte byte Byte unsigned char
Int16 short Short short
UInt16 ushort UInt16 unsigned short
Int32 int Integer int
UInt32 uint UInt32 unsigned int
Int64 long Long __int64
UInt64 ulong UInt64 unsigned __int64
Single float Single float
Double double Double double
Boolean bool Boolean bool
Char char Char wchar_t
String string String String
Object object Object Object

DO use a common name, such as value or item, rather than repeating the type name, in the rare cases when an identifier has no semantic meaning and the type of the parameter is not important.

Naming New Versions of an Existing API

DO use a name similar to the old API when creating new versions of an existing API. This helps to highlight the relationship between the APIs.

DO prefer adding a suffix rather than a prefix to indicate a new version of an existing API. This will assist discovery when browsing documentation, or using Intellisense. The old version of the API will be organized close to the new APIs, because most browsers and Intellisense show identifiers in alphabetical order.

CONSIDER using a brand new, but meaningful identifier, instead of adding a suffix or a prefix.

DO use a numeric suffix to indicate a new version of an existing API, particularly if the existing name of the API is the only name that makes sense (i.e., if it is an industry standard) and if adding any meaningful suffix (or changing the name) is not an appropriate option.

DO NOT use the “Ex” (or a similar) suffix for an identifier to distinguish it from an earlier version of the same API.

DO use the “64” suffix when introducing versions of APIs that operate on a 64-bit integer (a long integer) instead of a 32-bit integer. You only need to take this approach when the existing 32-bit API exists; don’t do it for brand new APIs with only a 64-bit version.

Names of Assemblies and DLLs

An assembly is the unit of deployment and identity for managed code programs. Although assemblies can span one or more files, typically an assembly maps one-to-one with a DLL. Therefore, this section describes only DLL naming conventions, which then can be mapped to assembly naming conventions.

DO choose names for your assembly DLLs that suggest large chunks of functionality, such as System.Data.

Assembly and DLL names don’t have to correspond to namespace names, but it is reasonable to follow the namespace name when naming assemblies. A good rule of thumb is to name the DLL based on the common prefix of the namespaces contained in the assembly. For example, an assembly with two namespaces, MyCompany.MyTechnology.FirstFeature and MyCompany.MyTechnology.SecondFeature, could be called MyCompany.MyTechnology.dll.

CONSIDER naming DLLs according to the following pattern: <Company>.<Component>.dll. where <Component> contains one or more dot-separated clauses.

Names of Namespaces

As with other naming guidelines, the goal when naming namespaces is creating sufficient clarity for the programmer using the framework to immediately know what the content of the namespace is likely to be. The following template specifies the general rule for naming namespaces:

<Company>.(<Product>|<Technology>)[.<Feature>][.<Subnamespace>]

The following are examples: CognitiveX.Math, Dovico.Security

DO prefix namespace names with a company name to prevent namespaces from different companies from having the same name.

DO use a stable, version-independent product name at the second level of a namespace name.

DO NOT use organizational hierarchies as the basis for names in namespace hierarchies, because group names within corporations tend to be short-lived. Organize the hierarchy of namespaces around groups of related technologies.

DO use PascalCasing, and separate namespace components with periods (e.g., Microsoft.Office.PowerPoint). If your brand employs nontraditional casing, you should follow the casing defined by your brand, even if it deviates from normal namespace casing.

CONSIDER using plural namespace names where appropriate. For example, use System.Collections instead of System.Collection. Brand names and acronyms are exceptions to this rule, however. For example, use System.IO instead of System.IOs.

DO NOT use the same name for a namespace and a type in that namespace.

For example, do not use Debug as a namespace name and then also provide a class named Debug in the same namespace. Several compilers require such types to be fully qualified.

Names of Classes, Structs, and Interfaces

The naming guidelines that follow apply to general type naming.

DO name classes and structs with nouns or noun phrases, using PascalCasing. Examples: User, Database, Order, LineItem.

This distinguishes type names from methods, which are named with verb phrases.

DO name interfaces with adjective phrases, or occasionally with nouns or noun phrases.

For example, IComponent (descriptive noun), ICustomAttributeProvider (noun phrase), and IPersistable (adjective) are appropriate interface names. As with other type names, avoid abbreviations. Names of interfaces end many times in -able, -Provider.

DO ensure that the names differ only by the “I” prefix on the interface name when you are defining a class–interface pair where the class is a standard implementation of the interface. Example: Component (class), IComponent (interface).

Nouns and noun phrases should be used rarely and they might indicate that the type should be an abstract class, and not an interface. Our example of Component and IComponent could also be solved by simply making Component an abstract class.

DO NOT give class names a prefix (e.g., “C”).

CONSIDER ending the name of derived classes with the name of the base class.

Base Class Derived Class
Validator
StringValidator
NumberValidator
RegexValidator
Field
StringField
NumberField
RegexField

This is very readable and explains the relationship clearly.

DO use reasonable judgment in applying this guideline; for example, the Button class is a kind of Control, although Control doesn’t appear in its name.

Names of Generic Type Parameters

DO name generic type parameters with descriptive names unless a single-letter name is completely self-explanatory and a descriptive name would not add value.

CONSIDER using T as the type parameter name for types with one single-letter type parameter:

public int IComparer<T> { ... }
public delegate bool Predicate<T>(T item);
public struct Nullable<T> where T:struct { ... }

DO prefix descriptive type parameter names with T:

public interface ISessionChannel<TSession> where TSession : ISession {
    TSession Session { get; }
}

CONSIDER indicating constraints placed on a type parameter in the name of the parameter. Example, a type parameter constrainted to ISession might be called TSession.

Names of Common Types

DO follow the guidelines described in the following table when naming types derived from or implementing certain .NET Framework types.

System.Attribute

DO add the suffix “Attribute” to names of custom attribute classes. add the suffix “Attribute” to names of custom attribute classes. Example:

public class IgnoreAttribute : Attribute {}

System.Delegate

DO add the suffix “EventHandler” to names of delegates that are used in events. Example:

public delegate void OnClickEventHandler(object sender, ClickEventArgs args);

CONSIDER adding the suffix “Callback” to names of delegates other than those used as event handlers. Example:

public delegate bool HandleMessageCallback(Message message);

DO NOT add the suffix “Delegate” to a delegate.

System.EventArgs

DO add the suffix “EventArgs.” Example:

public class ClickEventArgs : EventArgs {}

System.Enum

DO NOT derive from this class; use the keyword supported by your language instead; for example, in C#, use the enum keyword.

DO NOT add the suffix “Enum” or “Flag.”

System.Exception

DO add the suffix “Exception.” Example:

public class InvalidStateException : Exception {}

IDictionary
IDictionary<TKey, TValue>

DO add the suffix “Dictionary.” Note that IDictionary is a specific type of collection, but this guideline takes precedence over the more general collections guideline that follows. Example:

public class ClientAddressDictionary : IDictionary<Client, Address> { ... }

IEnumerable
ICollection
IList
IEnumerable<T>
ICollection<T>
IList<T>

DO add the suffix “Collection.” Example:

public class UserCollection : IList<User> { ... }

System.IO.Stream

DO add the suffix “Stream.” Example:

public class TCPIPStream : Stream { ... }

CodeAccessPermission
IPermission

DO add the suffix “Permission.”

Naming Enumerations

Names of enumeration types (also called enums) in general should follow the standard type-naming rules (PascalCasing, etc.). However, there are additional guidelines that apply specifically to enums.

DO use a singular type name for an enumeration unless its values are bit fields. Example:

public enum Severity { Mild, Medium, Serious, Nuclear }

DO use a plural type name for an enumeration with bit fields as values, also called flags enum:

[Flags]
enum Visibilities {
    Private = 1,
    Internal = 2,
    Public = 4
}

DO NOT use an “Enum” suffix in enum type names.

DO NOT use “Flag” or “Flags” suffixes in enum type names.

DO NOT use a prefix on enumeration value names (e.g., “ad” for ADO enums, “rtf” for rich text enums, etc.). Don’t do:

enum Visibility { visPublic, visInternal, visPublic }

Names of Type Members

Types are made of members: methods, properties, events, constructors, and fields. The following sections describe guidelines for naming type members.

Names of Methods

Because methods are the means of taking action, the design guidelines require that method names be verbs or verb phrases. Following this guideline also serves to distinguish method names from property and type names, which are noun or adjective phrases.

DO give methods names that are verbs or verb phrases:

public class String {
    public int CompareTo(...);
    public string[] Split(...);
    public string Trim();
}

Names of Properties

Unlike other members, properties should be given noun phrase or adjective names. That is because a property refers to data, and the name of the property reflects that. PascalCasing is always used for property names.

DO name properties using a noun, noun phrase, or adjective.

DO NOT have properties that match the name of “Get” methods as in the following example:

public string TextWriter { get {...} set {...} }
public string GetTextWriter(int value) { ... }

This pattern typically indicates that the property should really be a method.

DO name collection properties with a plural phrase describing the items in the collection instead of using a singular phrase followed by “List” or “Collection.”

DO name Boolean properties with an affirmative phrase (CanSeek instead of CantSeek). Optionally, you can also prefix Boolean properties with “Is,” “Can,” or “Has,” but only where it adds value.

CONSIDER giving a property the same name as its type.

For example, the following property correctly gets and sets an enum value named Color, so the property is named Color:

public enum Color {...}
public class Control {
    public Color Color { get {...} set {...} }
}

Names of Events

Events always refer to some action, either one that is happening or one that has occurred. Therefore, as with methods, events are named with verbs, and verb tense is used to indicate the time when the event is raised.

DO name events with a verb or a verb phrase.

Examples include Clicked, Painting, DroppedDown, and so on.

DO give events names with a concept of before and after, using the present and past tenses.

For example, a close event that is raised before a window is closed would be called Closing, and one that is raised after the window is closed would be called Closed.

DO NOT use “Before” or “After” prefixes or postfixes to indicate pre- and post-events. Use present and past tenses as just described.

DO name event handlers (delegates used as types of events) with the “EventHandler” suffix, as shown in the following example:

public delegate void ClickedEventHandler(object sender, ClickedEventArgs e);

DO use two parameters named sender and e in event handlers.

The sender parameter represents the object that raised the event. The sender parameter is typically of type object, even if it is possible to employ a more specific type.

DO name event argument classes with the “EventArgs” suffix.

Names of Fields

The field-naming guidelines apply to static public and protected fields. Internal and private fields are not covered by guidelines, and public or protected instance fields are not allowed by the member design guidelines.

DO use PascalCasing in field names.

DO name fields using a noun, noun phrase, or adjective.

DO NOT use a prefix for field names.

For example, do not use “g_” or “s_” to indicate static fields.

Naming Parameters

Beyond the obvious reason of readability, it is important to follow the guidelines for parameter names because parameters are displaysed in documentation and in the designer when visual design tools provide Intellisense and class browsing functionality.

DO use camelCasing in parameter names.

DO use descriptive parameter names.

CONSIDER using names based on a parameter’s meaning rather than the parameter’s type.

Naming Operator Overload Parameters

DO use left and right for binary operator overload parameter names if there is no meaning to the parameters.

DO use value for unary operator overload parameter names if there is no meaning to the parameters.

CONSIDER meaningful names for operator overload parameters if doing so adds significant value.

DO NOT use abbreviations or numeric indices for operator overload parameter names.

Naming Resources

Because localizable resources can be referenced via certain objects as if they were properties, the naming guidelines for resources are similar to property guidelines.

DO use PascalCasing in resource keys.

DO provide descriptive rather than short identifiers.

DO NOT use language-specific keywords of the main CLR languages.

DO use only alphanumeric characters and underscores in naming resources.

DO use the following naming convention for exception message resources.

The resource identifier should be the exception type name plus a short identifier of the exception:

ArgumentExceptionIllegalCharacters
ArgumentExceptionInvalidName
ArgumentExceptionFileNameIsMalformed