To underscore or to not to underscore, that is the question

Viewed 91161

Are there any problems with not prefixing private fields with an underscore in C# if the binary version is going to be consumed by other framework languages? For example since C# is case-sensitive you can call a field "foo" and the public property "Foo" and it works fine.

Would this have any effect on a case-insensitive language such as VB.NET, will there by any CLS-compliance (or other) problems if the names are only distinguishable by casing?

15 Answers

Taken from the Microsoft StyleCop Help file:

TypeName: FieldNamesMustNotBeginWithUnderscore

CheckId: SA1309

Cause: A field name in C# begins with an underscore.

Rule Description:

A violation of this rule occurs when a field name begins with an underscore.

By default, StyleCop disallows the use of underscores, m_, etc., to mark local class fields, in favor of the ‘this.’ prefix. The advantage of using ‘this.’ is that it applies equally to all element types including methods, properties, etc., and not just fields, making all calls to class members instantly recognizable, regardless of which editor is being used to view the code. Another advantage is that it creates a quick, recognizable differentiation between instance members and static members, which will not be prefixed.

If the field or variable name is intended to match the name of an item associated with Win32 or COM, and thus needs to begin with an underscore, place the field or variable within a special NativeMethods class. A NativeMethods class is any class which contains a name ending in NativeMethods, and is intended as a placeholder for Win32 or COM wrappers. StyleCop will ignore this violation if the item is placed within a NativeMethods class.

A different rule description indicates that the preferred practice in addition to the above is to start private fields with lowercase letters, and public ones with uppercase letters.

Edit: As a follow up, StyleCop's project page is located here: https://github.com/DotNetAnalyzers/StyleCopAnalyzers. Reading through the help file gives a lot of insight into why they suggest various stylistic rules.

It will have no effect.

Part of the recommendations for writing CLS-compliant libraries is to NOT have two public/protected entities that differ only by case e.g you should NOT have

public void foo() {...}

and

public void Foo() {...}

what you're describing isn't a problem because the private item isn't available to the user of the library

Since we are talking about a private field, it does not affect a user of your class.

But I recommend using an underscore for the private field, because it can make code easier to understand, e.g:

private int foo;
public void SetFoo(int foo)
{
  // you have to prefix the private field with "this."
  this.foo = foo;

  // imagine there's lots of code here,
  // so you can't see the method signature



  // when reading the following code, you can't be sure what foo is
  // is it a private field, or a method-argument (or a local variable)??
  if (foo == x)
  {
    ..
  }
}

In our team, we always use an underscore prefix for private fields. Thus when reading some code, I can very easily identify private fields and tell them apart from locals and arguments. In a way, the underscore can bee seen as a shorthand version of "this."

After working in a environment that had very specific and very pointless style rules since then I went on to create my own style. This is one type that I've flipped back and forth on alot. I've finally decided private fields will always be _field, local variables will never have _ and will be lower case, variable names for controls will loosely follow Hungarian notation, and parameters will generally be camelCase.

I loathe the this. keyword it just adds too much code noise in my opinion. I love Resharper's remove redundant this. keyword.

6 year update: I was analyzing the internals of Dictionary<TKey,T> for a specific usage of concurrent access and misread a private field to be a local variable. Private fields definitely should not be the same naming convention as local variables. If there had been an underscore, it would have been incredibly obvious.

I like the underscore, because then I can use the lowercase name as method parameters like this:

public class Person
{
    string _firstName;

    public MyClass(string firstName)
    {
        _firstName = firstName;
    }

    public string FirstName
    {
        get { return _firstName; }
    }
}

I still really like using underscores in front of private fields for the reason Martin mentioned, and also because private fields will then sort together in IntelliSense. This is despite the evilness of Hungarian prefix notations in general.

However, in recent times I find that using the underscore prefix for private members is frowned upon, even though I'm not quite sure why. Perhaps someone else knows? Is it just the prefix principle? Or was there something involved with name mangling of generic types that get underscores in them in compiled assemblies or something?

The _fieldName notation for private fields is so easy to break. Using "this." notation is impossible to break. How would you break the _ notation? Observe:

private void MyMethod()
{
  int _myInt = 1; 
  return; 
}

There you go, I just violated your naming convention but it compiles. I'd prefer to have a naming convention that's a) not hungarian and b) explicit. I'm in favor of doing away with Hungarian naming and this qualifies in a way. Instead of an object's type in front of the variable name you have its access level.

Contrast this with Ruby where the name of the variable @my_number ties the name into the scope and is unbreakable.

edit: This answer has gone negative. I don't care, it stays.

Update 2022

According to Microsoft documentation : C# Coding Conventions

Use camel casing ("camelCasing") when naming private or internal fields, and prefix them with _.

Benefit

When editing C# code that follows these naming conventions in an IDE that supports statement completion, typing _ will show all of the object-scoped members.

I think that by and large class-level fields are a mistake in the design of the language. I would have preferred it if C#'s properties had their own local scope:

public int Foo
{
   private int foo;
   get
   {
      return foo;
   }
   set
   {
      foo = value;
   }
}

That would make it possible to stop using fields entirely.

The only time I ever prefix a private field with an underscore is when a property requires a separate backing field. That is also the only time I use private fields. (And since I never use protected, internal, or public fields, that's the only time I use fields period.) As far as I'm concerned, if a variable needs to have class scope, it's a property of the class.

When you want your assembly to be CLS compliant, you can use the CLSCompliant attribute in your assemblyinfo file. The compiler will then complain when your code contains stuff that is not cls compliant.

Then, when you have 2 properties that only differ in case, the compiler will issue an error. On the other hand, when you have a private field and a public property in the same class, there will be no problems.

(But, I also always prefix my private members with an underscore. It also helps me to make it clear when i read my code that a certain variable is a member field).

Not to underscore. Because visually it looks too much like whitespace, not text. This affects readability of the indentation, which is how you understand the control flow of the code. [And it may needlessly trigger your carefully-honed badly-indented-code-detector reflex.]

Real world example...

        {
            Region = Environment.GetEnvironmentVariable(Dimensions.Names.REGION);
            if (xyz)
            {
                InstanceId = Environment.GetEnvironmentVariable(Dimensions.Names.INSTANCEID);
                _rawData = (long)0; // Disabled by default
            }
            _additionalDimensions = new Dictionary<string, string>();
        }

vs.

        {
            Region = Environment.GetEnvironmentVariable(Dimensions.Names.REGION);
            if (xyz)
            {
                InstanceId = Environment.GetEnvironmentVariable(Dimensions.Names.INSTANCEID);
                rawData = (long)0; // Monitoring disabled by default
            }
            additionalDimensions = new Dictionary<string, string>();
        }

I like to use underscores in front of my private fields for two reasons. One has already been mentioned, the fields stand out from their associated properties in code and in Intellisense. The second reason is that I can use the same naming conventions whether I'm coding in VB or C#.

Related