Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c#

People also ask

Why put an underscore in front of a variable?

A single leading underscore in front of a variable, a function, or a method name means that these objects are used internally. This is more of a syntax hint to the programmer and is not enforced by the Python interpreter which means that these objects can still be accessed in one way on another from another script.

Should I use underscore in variable names?

Variable names should not start with underscore ( _ ) or dollar sign ( $ ) characters, even though both are allowed. This is in contrast to other coding conventions that state that underscores should be used to prefix all instance variables. Variable names should be short yet meaningful.

Can you start variable name with _?

Variable name may not start with a digit or underscore, and may not end with an underscore. Double underscores are not permitted in variable name. Variable names may not be longer than 32 characters and are required to be shorter for some question types: multiselect, GPS location and some other question types.

What does an underscore signify?

One underscore signifies that the method is private, but can be called from the outside if we choose to do so in [11]. Two underscores preceding the function name make the method strictly private such that it cannot be called outside, as indicated by an error message for [12].


IMPORTANT UPDATE (April 12, 2016):

It was brought to our attention that the internal standard of the .NET CoreFX team insists on using the underscore-notation without giving any insights as to why. However if we look closely at rule #3 it becomes evident that there is a system of _, t_, s_ prefixes that suggests why _ was chosen in the first place.

  1. We use _camelCase for internal and private fields and use readonly where possible. Prefix instance fields with _, static fields with s_ and thread static fields with t_. When used on static fields, readonly should come after static (i.e. static readonly not readonly static).
  2. We avoid this. unless absolutely necessary.

So if you are just like .NET CoreFX team working on some performance critical, multithreaded, system level code, then it is STRONGLY SUGGESTED that you:

  • adhere to their coding standards and
  • use the underscore-notation and
  • don't read this answer any further

Otherwise please read on...

THE ORIGINAL ANSWER:

Let's first agree on what we are talking about. The question is how we access instance members from within non-static methods and constructors of a class/sub-classes if visibility modifiers allow doing so.

Underscore-notation

  • suggests that you use the "_" prefix in the names of private fields
  • it also says that you should never use "this" unless it's absolutely necessary

This-notation

  • suggests that you just always use "this." to access any instance member

Why does this-notation exist?

Because this is how you

  • tell apart a parameter from a field when they share the same name
  • ensure you are working in the context of the current instance

Example

public class Demo
{
   private String name;
   public Demo(String name) {
       this.name = name;
   }
}

Why does the underscore-notation exist?

Some people don't like typing "this", but they still need a way to distinguish a field and a parameter, so they agreed to use "_" in front of a field

Example

public class Demo
{
   private String _name;
   public Demo(String name) {
      _name = name;
   }
}

One may think it's just the matter of personal taste and both ways are equally good/bad. However there are certain aspects where this-notation beats the underscore-notation:

Clarity

  • underscore-notation clutters names
  • this-notation keeps names intact

Cognitive load

  • underscore-notation is inconsistent, it makes you treat fields in a special way, but you cannot use it with other members, every time you need to ask yourself whether you need a property or a field

  • this-notation is consistent, you don't have to think, you just always use "this" to refer to any member

Maintenance

UPDATE: as was pointed out the following isn't an advantage point

  • underscore-notation requires you to keep an eye on _ while refactoring, say turning a field into property (remove _) or the opposite (add _)
  • this-notation doesn't have such problem

Autocompletion

When you need to see the list of instance members:

  • underscore-notation doesn't help you much, because when you type "_" the autocomplete popup shows you the private fields and all types available from the linked assemblies mixed with the rest of the instance members
  • this-notation gives you a clear answer, by typing "this" all you see is the list of members and nothing else

Ambiguity

Sometimes you have to deal with the code without help of the Intellisense. For example when you do code reviews or browse source code online.

  • underscore-notation is ambiguous: When you see Something.SomethingElse you cannot tell whether Something is a class and SomethingElse is its static property... or maybe Something is a current instance property which has its own property of SomethingElse

  • this-notation is clear: When you see Something.SomethingElse it can only mean a class with a static property and when you see this.Something.SomethingElse you know that Something is a member and SomethingElse is its property

Extension methods

You cannot use extensions methods on the instance itself without using "this."

  • underscore-notation requires that you don't use "this", however with the extension methods you have to
  • this-notation saves you from hesitation, you always use "this", period.

Visual Studio support

  • underscore-notation doesn't have a built-in support in Visual Studio

  • this-notation is supported by Visual Studio naturally:

    1. "This." Qualification: Prefer all non-static fields used in non-static methods to be prefaced with this. in C#

Official recommendations

There a lot of official guidelines that clearly say "do not use underscores" especially in C#

  • underscore-notation came from C++ where it is a general practice which helps to avoid naming conflicts, also is recommended for VisualBasic.Net to overcome a problem where a field "value" and a property "Value" actually have the same name, because VisualBasic is case-insensitive
  1. Declared element names in Visual Basic
  2. Backing fields in VisualBasic.NET
  • this-notation is recommended for C# while "_" is explicitly prohibited:
  1. this keyword in C#
  2. Field usage guidelines: Do not apply a prefix to field names or static field names.
  3. Guidelines for names: Names of type members: Do not use a prefix for field names.
  4. General naming convention: X DO NOT use underscores, hyphens, or any other non-alphanumeric characters
  5. Quality assertion rule CA1707: Identifiers should not contain underscores
  6. Using underscores is not CLS compliant (for public and protected identifiers)
  7. Internal naming convention of .NET Framework developers: Do not use a prefix for member variables. If you want to distinguish between local and member variables you should use "this." in C# and "Me." in VB.NET.

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; }
    }
}