This article is the single most popular bit of content from my
old site and blog, bar none. While I think books such as the .NET Framework Design Guidelines by Krzystof
Cwalina and Brad Abrams do a better job explaining all the
standards, I've kept this page up for quick reference and to
support the schools and individuals currently using it.
Common .NET Naming Conventions
These are the industry-accepted standard naming conventions for
C# and VB.NET programs. For additional information, please see the
MSDN help documentation and the book referenced above. While
individual naming conventions at organizations may vary (Microsoft
only suggests conventions for public and protected items), the list
below is quickly becoming the de-facto standard in the industry.
Please note the absence of Hungarian Notation. These naming
standards should find their way into all of your .NET development,
including ASP.NET Web applications, WPF, Silverlight and Windows
Forms applications.
Note that while this document predates the online and printed
standards documentation from Microsoft, everything below which
indicates it is based on .NET library standards is consistent with
that documentation and Brad's book. In areas where Microsoft has
not provided guidance (Microsoft generally doesn't care what you do
in private/non-exposed code. In fact, they aren't even consistent
in their internal code in the .NET framework), de facto standards
have emerged, and I have captured them here.
The "ux" naming convention for controls is something I have
added and found to be helpful in Windows Forms, but not so much in
Silverlight and WPF. It is not based on any official standards, but
instead based upon a multitude of projects by my teams and others,
as well as on-line discussions on the topic. While I strongly
recommend that you follow Microsoft guidelines when present, I
encourage you to try out the items marked as extensions below and
see how they work for you before committing to them.
Type |
Standard / Convention |
Example |
Namespaces |
Standard Based Upon Microsoft .NET Library
Standards
Pascal Case, no underscores. Use CompanyName.TechnologyName as
root. If you don't have a company, use your domain name or your own
initials. Note that any acronyms of three or more letters should be
pascal case (Xml instead of XML) instead of all caps.
Why: This convention is consistent with the .NET Framework and
is easy to read.
|
AppliedIS.TimeCard.BusinessRules
IrritatedVowel.Controllers
PeteBrown.DotNetTraining.InheritanceDemo
PeteBrown.DotNetTraining.Xml |
Assemblies |
Standard Based Upon Microsoft .NET Library
Standards
If the assembly contains a single name space, or has an entire
self-contained root namespace, name the assembly the same name as
the namespace.
Why: This convention is consistent with the .NET Framework and
is easy to read. More importantly, however, it keeps your assembly
names and namespaces lined up, making it really easy to figure out
what is any particular assembly, and what assembly you need to
reference for any given class.
|
AppliedIS.TimeCard.BusinessRules.dll
IrritatedVowel.Controllers.dll
|
Classes and Structs |
Standard Based Upon Microsoft .NET Library
Standards
Pascal Case, no underscores or leading "C" or "cls". Classes may
begin with an "I" only if the letter following the I is not
capitalized, otherwise it looks like an Interface. Classes should
not have the same name as the namespace in which they reside. Any
acronyms of three or more letters should be pascal case, not all
caps. Try to avoid abbreviations, and try to always use nouns.
Why: This convention is consistent with the .NET Framework and
is easy to read.
|
Widget
InstanceManager
XmlDocument
MainForm
DocumentForm
HeaderControl
CustomerListDataSet (typed dataset)
|
Collection Classes |
Standard Based Upon Microsoft .NET Library
Standards
Follow class naming conventions, but add Collection to the end
of the name
Why: This convention is consistent with the .NET Framework and
is easy to read.
|
WidgetCollection |
Delegate Classes |
Standard Based Upon Microsoft .NET Library
Standards
Follow class naming conventions, but add Delegate to the end of
the name
Why: This convention is consistent with the .NET Framework and
is easy to read.
|
WidgetCallbackDelegate |
Exception Classes |
Standard Based Upon Microsoft .NET Library
Standards
Follow class naming conventions, but add Exception to the end of
the name
Why: This convention is consistent with the .NET Framework and
is easy to read.
|
InvalidTransactionException |
Attribute Classes |
Standard Based Upon Microsoft .NET Library
Standards
Follow class naming conventions, but add Attribute to the end of
the name
Why: This convention is consistent with the .NET Framework and
is easy to read.
|
WebServiceAttribute |
Interfaces |
Standard Based Upon Microsoft .NET Library
Standards
Follow class naming conventions, but start the name with "I" and
capitalize the letter following the "I"
Why: This convention is consistent with the .NET Framework and
is easy to read. It also distinguishes classes from interfaces,
where (unlike in VB6) are truly different beings. This avoid name
collisions as well, as it is quite common to have IFoo and a class
named Foo that implements IFoo.
|
IWidget |
Enumerations |
Standard Based Upon Microsoft .NET Library
Standards
Follow class naming conventions. Do not add "Enum" to the end of
the enumeration name. If the enumeration represents a set of
bitwise flags, end the name with a plural.
Why: This convention is consistent with the .NET Framework and
is easy to read.
|
SearchOptions (bitwise flags)
AcceptRejectRule (normal enum)
|
Functions and Subs |
Standard Based Upon Microsoft .NET Library
Standards
Pascal Case, no underscores except in the event handlers. Try to
avoid abbreviations. Many programmers have a nasty habit of overly
abbreviating everything. This should be discouraged. We're not
designing license plates or being charged by the letter :)
Functions and subs must differ by more than case to be usable
from case-insensitive languages like Visual Basic .NET
Why: This convention is consistent with the .NET Framework and
is easy to read.
|
VB: Public Sub DoSomething(...)
C#: public void DoSomething(...)
|
Properties and Public * Member Variables |
Standard Based Upon Microsoft .NET Library
Standards
Pascal Case, no underscores. Try to avoid abbreviations. Members
must differ by more than case to be usable from case-insensitive
languages like Visual Basic .NET.
Why: This convention is consistent with the .NET Framework and
is easy to read.
|
VB: Public Property RecordId As Integer
C#: public int RecordId
|
Parameters |
Standard Based Upon Microsoft .NET Library
Standards
Camel Case. Try to avoid abbreviations. Parameters must differ
by more than case to be usable from case-insensitive languages like
Visual Basic .NET.
Why: This convention is consistent with the .NET Framework and
is easy to read.
|
VB: ByRef recordId As Integer
C#: ref int recordId
|
Procedure-Level Variables |
Standard Based Upon De facto Industry-Accepted
Practices
Camel Case
Why: This convention is consistent with the .NET Framework and
is easy to read. It also avoids naming collisions with class-level
variables (see below)
|
VB: Dim recordId As Integer
C#: int recordId ;
|
Class-Level Private and Protected Variables |
Standard Based Upon De facto Industry-Accepted
Practices
Camel Case with Leading Underscore. In VB.NET, always indicate
"Protected" or "Private", do not use "Dim". Use of "m_" is
discouraged, as is use of a variable name that differs from the
property by only case, especially with protected variables as that
violates compliance, and will make your life a pain if you program
in VB.NET, as you would have to name your members something
different from the accessor/mutator properties.
Of all the items here, the leading underscore is really the only
controversial one. I personally prefer it over straight
underscore-less camel case for my private variables so that I don't
have to qualify variable names with "this." to distinguish from
parameters in constructors or elsewhere where I likely will have a
naming collision. With VB.NET's case insensitivity, this is even
more important as your accessor properties will usually have the
same name as your private member variables except for the
underscore.
As far as m_ goes, it is really just about aesthetics. I (and
many others) find m_ ugly, as it looks like there is a hole in the
variable name. It's almost offensive. I used to use it in VB6 all
the time, but that was only because variables could not have a
leading underscore. I couldn't be happier to see it go away.
Microsoft recommends against the m_ (and the straight _) even
though they did both in their code. Also, prefixing with a straight
"m" is right out. Of course, since they code mainly in C#, they can
have private members that differ only in case from the properties.
VB folks have to do something else. Rather than try and come up
with language-by-language special cases, I recommend the leading
underscore for all languages that will support it.
If I want my class to be fully CLS-compliant, I could leave off
the prefix on any C# protected member variables. In practice,
however, I never worry about this as I keep all potentially
protected member variables private, and supply protected accessors
and mutators instead.
Why: In a nutshell, this convention is simple (one character),
easy to read (your eye is not distracted by other leading
characters), and successfully avoids naming collisions with
procedure-level variables and class-level properties.
|
VB: Private _recordId As Integer
C#: private int _recordId ;
|
Controls on Forms |
An Extension to the Standards
May 2009 update
Note that I still consider this useful in many respects,
especially for intellisense grouping, but have backed away from
using this in recent projects, specifically Silverlight and WPF. I
still use an appropriate classification suffix such as Field or
Label (but not an actual control type) so that I can differentiate
between, say, the last name field and the label for it.
Examples would be LastNameField, LastNameLabel,
NextPageNavigation, PreviousPageNavigation. The classifications you
pick will need to make sense to you, and also allow for signficiant
flexibility for the designer of the UI to change the control type
in Xaml without you having to change the name in the storyboards
(runtime checked), code behind (compile-time checked), and control
lookups in code behind (runtime checked).
I backed away simply because it didn't look right in generated
member variables in my applications, or in the x:Name properties in
Xaml. It was a code smell issue, albeit a minor one.
Note also that in Silverlight and WPF, I only
name controls which need to be named because they are used in the
code behind or are referred to from a storyboard or relative
binding. The name is the primary contract between the code and the
visual design, and you want to keep that contract as small as
possible.
Note that I have seen the "ux" prefix in example code on the
net, and from Microsoft. Some folks still find it useful. You'll
need to make that decision for yourself.
I do not use the ux prefix when working in XAML-based uI, like
Silverlight
and WPF.
Original Information from 2002
In recent projects (since 2002 or so), I have taken to a single
prefix for all my UI controls. I typically use "ux" (I used to use
"ui", but it wasn't set apart well in intellisense). "ux" comes
from my usual design abbreviations where it means "User
eXperience", which has also since become a popular acronym. I have
found this to be extremely helpful in that I get the desired
grouping in the intellisense even better than if I use "txt", "lbl"
etc. It also allows you to change combo boxes to text boxes etc.
without having to change the names - something that happens often
during initial prototyping, or when programming using highly
iterative agile/xp methodologies.
Why: This convention avoids problems with changing control types
(textboxes to drop-down lists, or simple text box to some uber
textbox, or text box to date picker, for example), and groups the
items together in intellisense. It is also much shorter than most
Hungarian conventions, and definitely shorter and less
type-dependent than appending the control type to the end of the
variable name. I will use generic suffixes which allow me enough
freedom to change them around.
|
"ux" prefix
uxUserIdField, uxHeaderLabel, uxPatientDateOfBirthField,
uxSubmitCommand
no "ux" prefix
LastNameField, LastNameLabel, SubmitCommand,
NextPageNavigation
|
Constants |
Standard Based Upon Microsoft .NET Library
Standards
Same naming conventions as public/private member variables or
procedure variables of the same scope. If exposed publicly from a
class, use PascalCase. If private to a function/sub, use
camelCase..
Do not use SCREAMING_CAPS
Why: This convention is consistent with the .NET Framework and
is easy to read. A sizable section of the Framework Design
Guidelines is dedicated to why they chose not to go the
SCREAMING_CAPS route. Using SCREAMING_CAPS also exposes more of the
implementation than is necessary. Why should a consumer need to
know if you have an enum, or (perhaps because they are strings) a
class exposing public constants? In the end, you often want to
treat them the same way, and black-box the implementation. This
convention satisfies that criteria.
|
SomeClass.SomePublicConstant
localConstant
_privateClassScopedConstant
|
|
* Public class-level variables are universally frowned upon. It
is considered to be a much better practice to use property
procedures (accessors and mutators) to provide read and/or write
access to a private member variable. If you must expose a member
variable to other classes using "Public", follow the property
naming conventions, but don't complain if your guilty conscience
keeps you up at night ;-).
You Can find the standards for publicly exposed
classes/properties etc at
MSDN . If you want to run a tool to validate your code for
public standards and required practices, download FXCop or use the
analysis tools in Visual Studio.
Why Hungarian Has Fallen Out of Favor with .NET
With his simple question in my guestbook, Andrew Coupe
inspired me to write this little blurb here explaining why I feel
that Hungarian Notation has outlived its usefulness. If you're
sticking to Hungarian Notation in .NET, waffling, or just plain
curious - read on.
True Hungarian Notation is a naming convention invented by
Charles Simonyi from Microsoft back in the 70s. (For more
information on its origins, see this funny
article) Back in the day, one of the more promising versions of
Hungarian Notation was used in a way that indicated the purpose or
logical type of the variables rather than the language-specific
type. For example, instead of indicating something was an int, it
would be specified that it was an Id or a Quantity. When Hungarian
was used this way, it was very useful, especially in languages
where variable names were limited in length.
Shortly after the notation started being used, developers came
up with standard language-specific data-type based prefixes. I
remember when I worked in C/C++, we had things such as "rgsz"
meaning an array of zero-terminated strings (rg is short
for"reference to a graph" - an array in C/C++). This was useful for
a while, but the prefixes became unwieldy in both in length and in
understanding the permutations and combinations; you ended up with
things not too far from rgszxyzpdqOrderNo. Think
that's a stretch? Imagine what the name of a variable that
contained a long pointer to an array of arrays of long pointers to
some particular structure looked like when you mapped out the full
prefix. Yes, we really did have the occassional variable like that
in our programs, especially the database engine I worked on.
Then along came Visual Basic. This great rapid application
development tool introduced a lot of programmers to Windows
programming. Many them were brand new to programming, and gave
their variables meaningless or less than helpful, and almost always
inconsistent names. In response to this influx of bad code, good VB
developers started to use two different variations of the Hungarian
naming conventions. One was a traditional "as many letters as
needed" set with prefixes such as "s" for String, "i" for Integer,
and sometimes things like "arrl" for an array of longs. The second
school standardized on three letters for all prefixes "str" for
String, and "int" for Integer being two examples.
Some people took the conventions to extremes, and did silly
things like prefix database table names with "tbl", stored
procedures with "P", VB classes with "C" or "cls", and function
names with the Hungarian for their return type. That was and is
still just pure silliness, IMHO. I do, however, think that "I" in
front of an interface is important as interfaces need to be treated
very differently from classes.
During this time, VB4 and eventually VB5 and VB6 came out. VB4
introduced classes and some object-oriented language features to
these developers. Developers needed to remember to use "Set" when
assigning object variables, and had to remember to set them to
"Nothing" when they were done with them. To assist in remembering
to do this, developers would prefix all their object variables with
"obj" or "o". Typical code around this time was nothing but a ton
of variables with names like objResults and oHenry. It looked just
a bit odd, and wasn't particularly helpful.
Those of us who worked a lot with COM objects in Visual Basic
realized that the prefixes made no sense in public interfaces. In
fact, they looked plain awful. Many of us adopted conventions that
stated that anything exposed via COM would not have any prefixes
whatsoever. That included parameters, functions, classes, etc. This
was inline with what Microsoft and most 3rd-party vendors did with
all the COM libraries and ActiveX controls they provided.
At the same time, those of us working on large projects noticed
a definite laziness on the part of some other programmers (you know
who you are! <g>) when it came to updating the variable
prefixes when they changed a variable from, say, an Integer to a
Long. This caused far more confusion than was worth. When coupled
with the huge
multi-page lists of "all the prefixes" for every possible type
you could think of, Hungarian started to get in the way more than
it helped.
Along comes .NET and just about everything is
an object or can be boxed as such, and everything public is exposed
to other languages - languages which may not use the same names for
the variables we use (this was the same issue we had when writing
for COM). If I want to know a variable's type, I can hover over it
with the mouse in the VS.NET IDE. If I want to know a variable's
use, I simply look at the well-worded variable
name.
Now, rather than memorizing lists of prefixes, or prefixing
everything with "obj", programmers are able to concentrate on the
purpose of the variable rather than the underlying type. This alone
has increased programmer productivity by removing the requirement
to perform that mental prefix lookup - which for some of us was
like a SQL Server full-table scan <g>.
Since the .NET languages were a reasonably clean break from the
old versions, it made sense for Microsoft and .NET developers to
also change the expected naming conventions at the same time. They
knew the adoption of the new conventions would be more likely (and
less painful) with the platform shift.
.NET variables and types can have extremely long names, names
that can describe the purpose of a variable rather
than the underlying type. We don't have to pack as much meaning as
possible into just a few letters. Control-space makes typing the
long names completely painless, and the long names really assist in
understanding and documentation.
Some people still stick to the old Hungarian notation, but those
are the hold-outs. Sharing code with them becomes frustrating as
the conventions have to be all modified when you do so. If everyone
follows the Microsoft-recommended .NET conventions, information
exchange and collaboration becomes much easier :-) If you are one
of these hold-outs, and have good reasons for sticking to
Hungarian, I'd love to hear from you via the contact link at the
bottom of this page.
UI controls are something that are still in flux when it comes
to conventions. The reason Hungarian is still often used for them
is to ensure they are grouped in intellisense. Hungarian is
definitely not perfect for this, but it works.