Pete Brown's irritatedVowel.com
   home    wallpaper    railroad    .net, c#/vb    photography    birds    psp tubes    home/wood projects    games    recipes  
about   |   privacy   |   guestbook   |   pete's blog          
AddThis Social Bookmark Button

Section Contents
Naming Conventions and Standards
Best Practices
Links
Demos
HTTPModule Example
ASP.Net Cache API
AddThis Social Bookmark Button

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

If you find these to be helpful, be sure to drop me a note in my guestbook.

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

* 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 ;-).

Please don't copy and paste these conventions on your own site. Feel free instead to link directly to this page. That way you get the ability to automatically get updates when I make them, as well as get that warm fuzzy you get by not copying someone else's work. Schools and accredited educational institutions can paste these conventions on their own sites if and only if they include a direct link to this page an an attribution for the source of the information from "Pete Brown's irritatedVowel.com". Thank you for respecting my wishes on this.

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 2005+.

 

Sidebar: Database Naming Conventions

I've found the following naming conventions helpful when working in SQL Server.

Let's face it: when you work in SQL Server you already know what object is a table, perhaps what object is a view and what object is a stored proc. All the GUI tools put them in separate buckets. In the case of views, sometimes you'd rather not know. So instead of going by type, name your stored procedures by function and the object they work on, not with some standard prefix like "P" (or even worse, "sp_" - something that is contra-indicated by Microsoft for performance reasons).

When you name your procedures use "by" for the sort order, and "for" for criteria and start them off with the logical object name that the procedure works with. This makes it much easier to find specific procedures when you have a whole pile of them in a particular database. I also see no real reason for prefixes like "usp_" as all they do is add more characters to the name. Keep it simple, useful, and informative.

"Select" Stored Procedure Name Examples

CustomerGetSingleForID
retrieves a customer by ID

CustomerGetListAllByName
Retrieves a list of customers ordered by name. I usually use "lists" to populate drop-downs, pick lists etc, but not for updating. For that reason, lists often only have a few fields.

OrderGetListForCustomerIDByDate retrieves a list of orders for the customer, sorted by date)

Insert / Update / Delete Procedures

These are your typical CRUD procs that work on a single row in a dataset

CustomerUpdateSingle - update a single customer.

CustomerDeleteSingle - delete a single customer.

CustomerInsertSingle - insert a single customer.

Some people put an underscore after the object name in the stored proc: Customer_UpdateSingle. That looks fine to me as well. Either way, all the procedures related to a logical entity show up in the same location in the listings and trees in the various SQL Server management programs and add-ins.

So, what if the stored procedure updates multiple objects? No problem, just name it for what you would logically bundle those objects as. For example, if you have a procedure that updates an invoice and invoice line items all at once (admittedly a contrived example), you can logically consider it all to be an "invoice" and name it accordingly.

Others

Other stored procedures that are not simply CRUD-based are named based on what they do:

ProcessPendingOrders
CleanTempTables
MungeMyDatabase

Tables are named based on what they include. Table names and columns are Pascal case with no underscores. I won't get into the plural/non-plural bit as I unfortunately agree and disagree with both sides on that argument. heh.

NOTE: If you use strongly-typed datasets, you will find it makes a lot of sense to follow the PascalCase naming convention with your database tables and fields as well. That is because strongly-typed datasets are simply classes with properties for table field names.

Why Hungarian Has Fallen Out of Favor with .NET

With his simple question in my guestbook, Microsoft mid-atlantic's 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 everyghing 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. Email me at the webmaster address at irritatedVowel.com, or drop a note in my guestbook.

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.

Pete has absolutely nothing against Hungary, but just couldn't resist creating that little graphic :-)

Pete Brown is a lead Architect, Project Manager and (in the past) Instructor with well over 14 years of experience. That all being said, you are absolutely free to disagree with anything you see here, as long as you can make a rational argument :-)

Other Coding Style Tidbits

  • All - Use standard tab settings - don't change to 2 characters per tab or anything non-standard like that. Do not replace tabs with spaces.
    • Why: When people working in your code have different tab settings, it really makes a huge mess of the formatting. Whenever possible, I avoid fighting the IDE and just go with the flow.
  • C#/J#/C++ - Keep your curly braces on lines by themselves. Don't put the opening curly brace at the end of the line. If you run across code that does this, simply delete the last curly brace in the code module, and retype it. VS.NET will correct all the other braces for you automatically.  The exception is single line statements, such as the accessor "get" in a property that simply returns a variable: get { return _privateVariable ; }
    • Why: This is another "don't fight the IDE" issue. Unless your entire team, and everyone who modifies the code later has changed their default settings, you will all be fighting the IDE. VS 2005 is a bit more forgiving on this front, but is it really worth the hassle?
  • All - Use Andale Mono or Consolas as your code editor font. This is much easier on the eyes than Courier New. Andale Mono used to be free from Microsoft, but can be hard to find. It's out there on the net, though, as a free download. Consolas comes with Vista as well as with the latest versions of Microsoft Office (2007 and above). You can find Consolas here. Please note that Consolas looks terrible unless you have full ClearType font smoothing running on XP, or are using Windows Vista or better.
    • Why: these fonts are generally easier on your eyes and are optimized for development
  • C# - use the triple-hack XML comments "///" for all functions and classes. in VB.NET, use "'''" in VS 2005 and above (that's ' ' ' without the spaces)
    • Why: This will facilitate generating a document containing all the code documentation for your project.

who's online