Naming Conventions
General
Casing
Use Pascal-casing (first letter of each word in uppercase) unless otherwise specified.
Do not use names that differ only in case. These can be hard to identify and can lead to errors; especially, when components are being used by languages which are not case-sensitive.
Two-letter acronyms should be in uppercase, while three-or-more-letter acronyms should use Pascal-casing (i.e. System.IO and System.Xml).
Code analysis messages CA1705 Long Acronyms Should Be Pascal-Cased (http://msdn2.microsoft.com/en-us/library/ms182249(VS.80).aspx) and CA1706 Short Acronyms Should be Uppercase (http://msdn2.microsoft.com/en-us/library/ms182256(VS.80).aspx).
Common, Recognizable Words
All names should be explanatory – avoid numbers except in cases like: Step1, Step2, etc.
Every attempt should be made in providing plain English names to all elements described in this document. Non-project personnel should be able to understand the element names when needed. Common sense should prevail in choosing names.
Keep in mind in choosing names as to the contextual differences some words mean to different people. For example, the words “base” and “unit” mean entirely different things to military personnel than civilian personnel.
Other
Limit the use of underscores. The most common use of underscores is to separate the words in constants that are completely in uppercase. Class and property names should not contain underscores unless required for absolute readability.
Do not use long (more than 15 character) names, where possible. Long names can cause confusion and will decrease readability.
Do not use literal values in code; instead, use constants.
Projects and Namespaces
Project should be the same as the root namespace unless another naming standard exists when creating projects to be used with third-party software. Namespaces must be in the form: Organization.[Suite.]Application.Component.*. For example, the Automated Polling Module is managed by Contoso, so it would be Contoso.Apm.*. This base namespace should be used for all subprojects within the application. Additionally, if an application is part of a suite of tools, the suite name should precede the application name. For instance, Excel and Word are part of the Microsoft Office suite and would use the following namespaces: Microsoft.Office.Excel and Microsoft.Office.Word.
Be consistent across the application and model namespaces after the .NET Framework (i.e. data components in the RootNamespace.Data namespace).
Namespace names should be the same as directory names. This enhances maintainability by providing implicit architectural insight via the directory structure.
Use plural namespace names where appropriate. This tells developers that a namespace consists of various objects of that type. For instance, System.Collections contains collection classes and System.Web.Services contains web services support.
Avoid naming the namespaces the same as any related class. This can cause confusion and even require different usage practices to be taken into account when working with different .NET languages.
Type Names
Classes and structures represent objects. Based on this, nouns or noun phrases should be used in all circumstances (i.e. User or UserProvider). Interface names can also use adjectives to describe the behavior of that object (i.e. ISerializable).
When extending classes or implementing interfaces, name the child class after the parent object, when applicable. This will allow others to visibly recognize the purpose of the object and/or its capabilities.
public interface IComponent
public class Component : IComponent
public class abstract CollectionBase
public class MyCollection : IComponent
Avoid naming the types the same as any related namespace. This can cause confusion and even require different usage practices to be taken into account when working with different .NET languages.
Code analysis message CA1724 Type Names Should Not Match Namespaces (http://msdn2.microsoft.com/en-us/library/ms182257(VS.80).aspx).
Reference the following table when naming your object types. This will help ensure the different object types are identifiable when used in code.
| Object Type |
Name |
Example |
| Class, Abstract |
*Base |
class CollectionBase : IList, ICollection, IEnumerable |
| Class, Attribute |
*Attribute |
class Attribute : Attribute |
| Class, Collection |
*Collection |
class StringCollection : CollectionBase |
| Class, EventArgs |
*EventArgs |
class MouseEventArgs : EventArgs |
| Class, Exception |
*Exception |
class SystemException : Exception |
| Delegate |
*EventHandler |
delegate ClickEventHandler(object sender, EventArgs e) |
| Interface |
I* |
class ICollection |
| Method, Event-Raising |
On* |
protected virtual void OnClick(MouseEventArgs e) |
Code analysis messages CA1710 Identifiers Should Have Correct Suffix (http://msdn2.microsoft.com/en-us/library/ms182244(VS.80).aspx) and CA1715 Identifiers Should Have Correct Prefix (http://msdn2.microsoft.com/en-us/library/ms182243(VS.80).aspx). The above table is only a partial list of the most used values.
Enumerations
Use singular names for enumerations and plural names for bit fields.
Use the Flags attribute when defining an enumeration whose values are intended to be either bitwise or used together.
[Flags]
public enum Bindings
{
CreateInstance = 0,
DefaultBinding = 1,
ExcatBinding = 2,
GetField = 4,
GetProperty = 8,
IgnoreCase = 16,
InvokeMethod = 32,
NonPublic = 64,
OABinmding = 128,
SetField = 256,
SetProperty = 512,
Static = 1024
}
Bindings bindings = Bindings.IgnoreCase | Bindings.SetProperty;
When encapsulating a Win32 API, use the standards that apply to that API. This may mean that naming and casing conventions may be sacrificed for understandability when compared to other Win32 code-bases.
Events and Event Handlers
Events are actions, verbs or verb-noun phrases should be used in all circumstances (i.e. Click or Execute).
Name events according to when they will be raised. Avoid using the “Before” and “After” prefixes. Instead, use present and past verb tenses, respectively.
public event ChangeEventHandler ValueChanging;
public event ChangeEventHandler ValueChanged;
Code analysis message CA1713 Events Should Not Have Before or After Prefix (http://msdn2.microsoft.com/en-us/library/ms182238(VS.80).aspx).
Use the standard two parameters for all event handlers (delegates), sender and e. The sender parameter represents the object that raised the event, which should always be of type object. For specialized properties that might need to be accessed by the event handler, customize the event argument class that is passed as the parameter e. This will ensure a standard implementation for all event handlers that is known and understood by others.
public delegate ClickEventHandler(object sender, MouseEventArgs e)
For each event within a class, provide a corresponding protected virtual method that raises the event. This is not appropriate for sealed classes, because they cannot be sub-classed. The purpose of the method is to provide a way for a subclass to handle the event using an override. This is more natural than using delegates in the case where the developer is sub-classing. The name of the method should be prefixed by On.
private ChangeEventHandler _changeHandler;
protected virtual void OnClick(MouseEventArgs e)
{
if ( this._changeHandler != null )
{
this._changeHandler(this, e);
}
}
This will allow subclasses to be either completely remove, replace, or simply extend base classes events with a complete
Methods
Methods are actions; verbs or verb-noun phrases should be used in all circumstances (i.e. Sort() or GetType()).
Method names should not specify the return type, unless required (i.e. ToString()). Often during the life of a system, return types will change. Such a change may require a vast amount of refactoring, if the method name would also change.
Fields, Properties, Variables, and Parameters
Fields are direct-access members and properties are indirect. Properties provide getters and setters to obtain access to data values. In most cases, fields will be private and properties will be public; however, this is not always true. Recognizing this distinction is important.
General
Properties are objects; nouns and noun phrases should be used in all circumstances. Boolean values can also use adjectives to describe the intended purpose of that property (i.e. Visible). In most circumstances, Boolean variables should be prefixed by Is, Can, Has, or a similar word that reiterates their yes/no or true/false nature.
Avoid naming members, variables, and parameters the same as types and/or related namespaces. This can cause confusion and even require different usage practices to be taken into account when working with different .NET languages.
Code analysis messages CA1718 Avoid Language Specific Type Names in Parameters (http://msdn2.microsoft.com/en-us/library/ms182233(VS.80).aspx) and CA1720 Avoid Type Names in Parameters (http://msdn2.microsoft.com/en-us/library/ms182234(VS.80).aspx).
Do not specify member names that repeat the class name (i.e. Book.BookTitle), doing so is redundant.
A particular class can have one and only one index property, which should be named Item unless there is an obvious better name.
Use the property getter and setter instead of the private field. This practice ensures domain logic embedded in the getter/setter is always used and lessens the chance of using data that hasn’t been filtered through necessary getter/setter logic. Obvious exceptions to this rule include initializing a read-only property in the class constructor, for instance.
Code analysis message CA1051 Do Not Declare Visible Instance Fields (http://msdn2.microsoft.com/en-us/library/ms182141(VS.80).aspx).
Do not use terms such as Flag when naming status variables. Instead, use a more meaningful name that describes the purpose of the variable (i.e. Instead of documentFlag, use documentFormatType).
Use single-letter variable names for short loop indexes only.
Properties
Properties should be named after the private field they are controlling access to (i.e. Visible hides _visible). This will ensure that others can recognize the relationship between the two without reviewing documentation.
Fields
Prefix all private fields with an underscore (“_”) and use the camel-case version of the corresponding property name. This will allow maintainers to identify at a glance what properties are public/protected or private.
private string _name;
public string Name {...}
Code analysis messages CA1500 Variable Names Should Not Match Field Names (http://msdn2.microsoft.com/en-us/library/ms182216(VS.80).aspx), CA1708 Identifiers Should Differ by More than Case (http://msdn2.microsoft.com/en-us/library/ms182242(VS.80).aspx), and CA1709 Identifiers Should Be Cased Correctly (http://msdn2.microsoft.com/en-us/library/ms182240(VS.80).aspx). These are a partial justification for the underscore prefix, which, in part, will ensure field-variable conflicts will be avoided.
Use Pascal-casing (first letter of each word in uppercase) for all constants, no matter what their visibility.
When referencing private fields, always use the appropriate class identifier (i.e. this or Me).
Local Variables and Parameters
Use camel-casing (first letter of each word in uppercase except for the first word).
Use Hungarian notation (prefix the variable name with a type identifier). This is required in VB because of limitations put in place by case-insensitivity.
Use parameter names based on the parameter’s meaning instead of its type. Occasionally, type-based names are appropriate, however.
Operator Overloading
Use operator overloading on appropriate user-defined value types.
Avoid frivolous use of operator overloading. Operator overloading should only be used for user-defined types and in scenarios where it is apparent that their use is valid and necessary to increase efficiency. For instance, subtracting two Time values logically makes sense to return a TimeSpan, while a bitwise or (“|”) operation between two DataSet objects is not an appropriate data merging practice.
Not all languages support operator overloading. To ensure capabilities are available to all languages, provide a method that accomplishes the work of each overloaded operator.
public class Time
{
public TimeSpan operator –(Time t1, Time t2) {...}
public TimeSpan Difference(Time t1, Time t2) {...}
}