Saturday, May 24, 2008

.NET Programming Standards and Naming Conventions

Common .NET Naming Conventions

These are the industry-accepted standard naming conventions for J#, C# and VB.NET programs. For additional information, please see the MSDN help documentation and FX Cop. 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 except in visual controls. These naming standards should find their way into all of your .NET development, including ASP.NET Web applications and .NET 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. 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 consistant 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. 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.



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



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



uxUserID, uxHeader, uxPatientDateOfBirth, uxSubmit







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



2 comments:

NR said...

Good one... I also use leading _ for private/protected. Thanks for the ux, sounds much better than refactoring.

Ionut Pop said...

I guess I'm an old school holdout, even though I didn't know I was old school. I learned VB.NET in 2003, and have developed a number of programs along the way in my position as the only IT person in the place, so I was not exposed to anything different than what I had been taught. Now I'm going through C# 2010 Step by Step by John Sharp, and when I got to the section on WPF I was shocked that the text box was named "FirstName" and not "txtFirstName", so I did a search on c# naming conventions and found this page. Thank you - it is quite enlightening. I'll have to give this a try to see how I like it. Thanks.

Ionut from Real Madrid