다음을 통해 공유


Variable names in C# (my 2¢)

I've gotten to the point that I've seen a lot of .Net source and a lot of different styles.  After a while it becomes pretty easy to know a lot about a particular coder from his style.  I'll look at one person's application source and think, “Hey, that's a VB 6 dev moving into C#“ and another where I'll think, “C++ guy who was drilled on Hungarian until he can't read code without it.“  When I say style, I'm not talking about higher level issues, like encapsulation, code reuse, and class hierarchies -- I'm just talking about the internal and private names we use in our own coding.  There's plenty of information on what your interfaces should look like externally (https://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/cpconnetframeworkdesignguidelines.asp). But there's a diverse array of thinking on internal naming convention.

There are four issues that need to be addressed when choosing internal naming style, and each of these are going to be situational. You might end up going different ways on these issues based on project scale, complexity, and tools. I'll talk about part 1 today and the last 3 parts tomorrow.

  1. Should a variable name indicate what it does or what it is?
  2. How should a variable name indicate it's scope (member versus local versus static versus parameter names)?
  3. How descriptive should a variable name be (and when should you abbreviate)?
  4. How do you categorize (group) variables by name (particularly when using Intellisense)?

 

And before I start going on about any of these, I'll talk a little bit about my more firm style points. Again, these aren't “official“ rules, these are just peronal rules I've developed while writing (and reading!) lots of managed code.

  • Camel case all private, internal, and locally scoped variables. No underscores!
    • Examples
      • FOO ---> foo
      • foo_bar --->fooBar
      • Hi_There ---> hiThere
  • Avoid bunching capital letters
    • Examples
      • MDXTest ---> mdxTest
      • OPEC ----> opec
      • parsedHTML ----> parsedHtml
    • Grey Areas (in these cases, I usually opt to find a better name for the variable)
      • hiIAmAVariable ----> hiIAmAVariable (ok, but a little “loud”) hiIamAvariable (follows rule, but hard to read, I would avoid this)
  • Avoid number names
    • There are almost always better ways to describe by function
    • Examples
      • run1, run2 ---> runInitialize, runValidate

Should a variable name indicate what it does or what it is?

The first question addresses the most general aspect of the variable name: does it indicate function or type. Now the rule for external api's is that a name should always explain function. The idea that type-safing and meta data provides enough information about the variable to indicate it's usage. However, there might be cases (particularly internally) where you may be introducing ambiguity by not specifying type. The easiest scenario would be when using unsafe data. In this case it may be important to specify the type of a void pointer (if known). 

Your tools may also determine your naming. I'm fairly spoiled in that I use the Visual Studio IDE almost exclusively. If I ever need to know the type of something quickly, I can float my mouse cursor over it and I know instantly what it is. However, there are plenty of teams that don't use fancy text editors and some that use plain old notepad (I still use it myself from time to time). Lets say that same notepad.exe user is dealing with a several highly abstract DOM objects like those used to represent XML documents. In this case, it may be helpful to distinguish between an XmlNode object and a string containing the XML data. In these cases, I'll usually just spell out the type, so that XmlNode might be myHeaderNode and the String would be myHeaderString.

A final case for using type names might be when using a lot of polymorphism and casting. Take the following (somewhat nonsensical) example:

private class MySuperClass { }
private class MyHappySubClass : MySuperClass{ }
private class MySadSubClass : MySuperClass { }

public void SomeFunction(MySuperClass thing) {

...determine that thing is of type MySadSubClass

MySadSubClass sadThing = (MySadSubClass) thing;

}

In this example, we're casting an instance of MySadSubClass to a local MySadSubClass variable to make it easier to work with. There are some times when you'll want to determine the actual type of an incoming object at runtime and do some specific operation on it. Managed code makes it easy to reflect the type of an instance. In this case, we want to emphasize that “sadThing” is the same instance as “thing”, but we also want to indicate its type to avoid confusion when operating on the specific functionality defined by the subclass. Again, this is a pretty forced example -- there are plenty of reasons not to try to reflect the type of an instance for specific use at runtime, but if the situation is unavoidable, this naming convention can help sort things out.

To be continued....

Comments

  • Anonymous
    July 08, 2004
    Avoid names with numbers? Visual Studio thinks naming variables TypeX is a perfectly normal thing to do. And since a lot of "programmers" never actually touch the code you would be surprised how many people use variable names Edit1, Edit2, Edit3 and so on.
  • Anonymous
    July 08, 2004
    Well, I personally avoid designers, but I can totally understand why the visual studio tools enumerate control names with numbers. I'll occasionally use a designer for a winform. When I do, I'm fairly careful to change the control names to something descriptive. Most of the time, I use the designer as a one-time development helper, but then drop the wizard code and organize control initialization into my own sections.

    I have seen a lot of "release" application / tools code with numbered variable names, and it never fails to irk me. The best way to think of the Visual Studio control names are as temporary placeholders for one's own descriptive names.
  • Anonymous
    July 08, 2004
    I have an issue with this:

    "How should a variable name indicate it's scope (member versus local versus static versus parameter names)?"

    Personally, I think the more pertinant question is: Should a variable name indicate its scope?

    I used to prefix fields with an underscore, because it helped me to mentally seperate them from locals (and was the simplest, least-intrusive marker I could think of). Three things have changed that opinion. The first was the realisation that most of the time I didn't have to care about the scope of a variable anyway. The second was that if I have trouble identifying locals within a method, that method is too big. The third was JetBrains' ReSharper tool, which colours fields and locals differently. The last is probably the least contentious - Visual Studio already colours language keywords, comments and compiler errors, so why isn't that extended to other elements?
  • Anonymous
    July 08, 2004
    "Camel case all private, internal, and locally scoped variables."

    My exception to that rule is "unless encollapsed by property." To me, that just shows the relation that a field has.
  • Anonymous
    July 09, 2004
    "Personally, I think the more pertinant question is: Should a variable name indicate its scope? "

    I will be addressing that actually. I'm of the opinion that there are times for both schools of thought -- but I'll get into that in my next post.