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 |
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