I am about to embark on the “religious” topic of naming conventions. I was reminded of this topic by the short post, “Hungarian Notation, what do I think”, by Richard Dingwall.
I’m sure there will be those of you who will disagree with me, but as I’ve stated in previous posts, these general guidelines I’ve been using for .NET programming have served me well since .NET 1.0; they are meant as strong suggestions for those who are looking for guidance, not rules I expect the industry to adopt because I know better than anyone else.
In fact, while I will propose what I consider the “best” way, I will also provide some alternatives.
In the early days of programming, particularly in the VB4, 5, and 6 days as well as the early days of C/C++ our IDEs were limited in the information they could give us about the variables we were working with. We also had the problem of scattered variables. We might create a variable in one file and use it in another. Because of this, we were taught to prefix the name of our variables with a notation that told the programmer where the variable was created and what type of variable it was. This was both useful and functional because in the procedural world that this was primarily suggested, there were a limited number of variable types and a limited number of places where a variable could be created.
Things got a bit more complex as we moved toward object-oriented programming.
Object-Oriented Programming Messes Things Up
With the advent of OOP, several factors inherent in the methodology make Hungarian Notation, as it had come to be called, difficult to implement well.
First, the concept of encapsulation limits the number of places a variable could be created. We can now create a local variable inside our methods or a member variable that is part of our class. This alone eliminates, or at least severely limits, the need for Hungarian Notation.
Second, any access to the member variable from another, outside class, should be through a method or property of the class the member variable is in. I don’t know about you, but I’ve never seen a property in a commercial class called strFirstName.
Third, the ability to create our own variable types through classes and structures means we either prefix all of our variables with the class or structure type or we prefix them with the completely useless information that it is a variable of type class or structure.
I’ve also seen cases where the class is declared prefixed with a C and the variables that are of type class get prefixed with an “o” (for object).
The Development Environments are Much Better
As I mentioned earlier, the development environments we were working with at the time were not very good about telling us what the data type of the variable we were working with was. This made the pain of prefixing the variable worth the effort. But with the current state of the IDEs available, it just isn’t worth the effort, or the associated problems that come with this type of naming convention.
It Wasn’t a Particularly Good Idea to Start With
The last issue I have with Hungarian Notation is that if the type of the variable changed, say, from an integer to a long integer, we had to rename the variable every place we used it. If that variable was being used in multiple files through out the system and the system was relatively large, just that tiny change could take a very long time to implement.
Of course, now we have an IDE that will do the work for us, but with all of the other reasons for not using it, does it really matter?
It’s Not All Bad, Though
By this point, you might think that I am suggesting that we not use any naming conventions at all. Nothing could be further from the truth.
Even though variables can only be located in one of two places, local to the method or as a member of the class, I do find it helpful to prefix my member variables with an “m_” prefix. This allows me to use variable names in my method and variable names in my class that both have essentially the same name (firstName vs m_firstName) with a certain amount of clarity. It also allows me to use intellisense to access my member variables, “this.m_” brings up a list of all my member variables in CSharp and “me.m_” brings them all up in VB.NET. For those of you still using Modules in VB.NET, you might also consider using g_ if you have a variable that is going to be globally accessed. I would suggest that you eliminate your modules and use classes with static methods instead. This is what they get converted into when you compile your code anyhow.
I’ve also seen “_” used instead of “m_”. This is fine as long as you are consistent.
In general I just call my variables what they are going to be used for without prefixing them with any information about what type they are. However, I’ve found it useful, especially in ASP.NET programming, to prefix my controls which information about what control they are. I’m not cryptic about it either. I prefix my buttons with “m_button” or my TextBoxes with “m_textBox”. The “m_” is because the controls are members of the page class. So, my OK button would be represented by m_buttonOk.
An object-oriented purist might say that what we should do is name the button, “m_okButton” because that’s what it is. However, I’ve found that prefixing the variable makes me more productive. I’m a lot more likely to remember that I’m looking for a text box control when I’m programming my codebehind than I am to remember what I called it. So, I can type “m_textBox” in my IDE and intellisense brings up my list of textBox controls where I can pick the one I want.
You’ll notice that I’m not cryptic about my naming either. In the early days, we had 32 characters, or less, to name a variable with so it was important that our naming convention take up as little room as possible so that we could use the rest of our space to name the variable what it was being used for.
Now we have at least 256 character and we can afford to be as descriptive as we need.
One of my clients argued that spelling everything out made us type more and therefore argued for a more cryptic naming convention that abbreviated the control. tb for textBox, l for Literal and Label, etc. It achieves most of the purposes I’ve outlined above but it does get confusing sometimes when I’m working with a control prefixed with an “m_l”. Is that a Literal or a Label?
Naming Classes and Modules
Finally, we need to talk about naming conventions for the various files in our applications. What do we name Forms, User Controls, Web Pages, etc.?
I’ve seen some who want to prefix the type of file with information about the class inside it. frm for Forms, cls for regular Classes, uc for User Controls.
I presume this is useful so that the classes in those files are easy to find. All my Forms are grouped together, all my regular classes are grouped together, etc.
But an alternate way of doing this would be to create subdirectories for each group. Placing all of your user controls in a “controls” directory, all of your business logic layer classes in a “bll” directory, etc. actually ends up making your project much more manageable than placing all of your files in the root directory of the application and having to scroll to the “uc” prefixed files.
Whatever naming convention you use, it is important that you remain consistent as much as possible. If you are already in an organization that is doing it “wrong,” suck it up and do it their way, as long as they are consistent. If there is no consistency, I guess you are free to do it whatever way you want, but if it were me, I’d try to first argue for consistency and then argue for a naming convention like I’ve outlined above.