44

I saw this at an MVC3 Razor tutorial at http://www.asp.net

public ActionResult Index() {

    return View(_usrs._usrList);

}

Isn't that usage plain wrong? I have always thought that [docs]

In C#, I usually see it used only when defining the underlying private member variable for a public property. Other private member variables would not have an underscore. This usage has largely gone to the wayside with the advent of automatic properties though.

Or is it a new naming convention I am seeing? Very curious about that usage in Microsoft's own tutorial.

P.S: The article is pretty good. Its just that I tend to follow naming conventions for better readability.

Community
  • 1
  • 1
naveen
  • 53,448
  • 46
  • 161
  • 251
  • 4
    I use underscores always for private members, makes them easier to find. `_MyVariable` isn't destroying the readability. – Felix K. Mar 20 '12 at 07:37
  • 1
    Eww, a method with the name of a property. That should be GetIndex() of course. Written by a C++ programmer, probably. All pretty subjective, use your own conventions. – Hans Passant Mar 20 '12 at 11:22

4 Answers4

60

A good article to read on the development of C# style guidelines is here at C# coding conventions.

The original guidance for .NET was to never use underscores unless they were part of a private member variable, and then only as a prefix, e.g. _customerId. This was probably inherited from MFC where 'm_' was used as a prefix for member variables.

Current practice is not to use underscores at all. Disambiguation between private member variables and parameters with the same name should done using 'this.'. In fact all references to private members should be prefixed with 'this.'.

The only place underscore seems to be used a lot is in unit test methods. I'm not a fan, but it may make the methods more readable, for example Throw_If_Customer_Is_Null(){...}.

David Tejuosho
  • 177
  • 1
  • 14
Phil
  • 42,255
  • 9
  • 100
  • 100
  • never heard that recommendation around use of "this". Thanks. – cori Mar 21 '12 at 04:31
  • 42
    I still can't make myself switch to using 'this.'. It just doesn't feel right :-) – Phil Mar 21 '12 at 07:10
  • so it did change... i was wondering why samples ignored it. i still don't really like it. i know people who would get confused by that. _something is still shorter than this.something too... guess i'll just stick to underscore – Dbl Oct 17 '14 at 08:41
  • 5
    `Disambiguation between private member variables and parameters with the same name should done using 'this.'` - Resharper warns you if you use `this` to refer to member fields inside methods in C# classes. It suggests to remove `this` qualifier as a potential fix for such source code. I'm using Resharper 2016 Ultimate. – RBT Apr 18 '17 at 02:38
  • 4
    This is Microsoft's guidance, accurately presented, though note that this advice causes `SomeProperty`'s backing field to be `someProperty`, if you then accidentally type `get {return SomeProperty}` in the property definition you will get a `StackOverflowException` every time it's called; I'm not thrilled that this naming scheme always has me one typo away from a runtime error / crash. Also it might be worth mentioning that the [.NET framework itself](https://referencesource.microsoft.com/#System/net/System/Net/Sockets/TCPClient.cs,21) seems to prefer `m_` instead of their official guidance. – jrh Oct 26 '17 at 12:42
  • Also in case anyone's wondering, no, I can't replace all backing fields with auto-properties. A third party library we are using does not properly support `{get; private set}`. Also be aware of cases where you can accidentally generate no-op code using typos, like `someData = someData`, where `data` is a parameter and a field. There's a warning in VS for this now, it needs to be `this.someData = someData` – jrh Oct 26 '17 at 12:45
  • 2
    @RBT - that is a configurable setting – Stephen Drew Nov 07 '17 at 23:03
  • 2
    Update: ["Internal and private fields are not covered by guidelines"](https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/names-of-type-members); so the "current practice" in "Current practice is not to use underscores at all." doesn't refer to any current Microsoft guideline, though IIRC there used to be an official guideline saying that. I'd recommend updating this answer to make this more clear. – jrh Jan 24 '18 at 15:33
  • 13
    Using `this` as an indicator of privacy is a redundant eyesore. – ChiefTwoPencils Apr 10 '18 at 14:26
  • 1
    Yes agreed, I never used this. to be honest. – Phil Apr 14 '18 at 14:51
  • 3
    So `this.` is ambiguous and adds no extra information? But an underscore does? Well, the `this.` is better as removes ambiguity for sure with the help of the compiler. Duh – Fabio Milheiro Mar 16 '19 at 00:13
  • In your comment you write "Yes agreed, I never used this. to be honest." but in your answer you write "In fact all references to private members should be prefixed with 'this.'." - please decide... – BornToCode Jun 26 '19 at 09:24
  • The problem with "this." is it puts the burden on the future writer to honor the convention on every future usage. Whereas if you agree on "_" the convention is locked in from the outset and cannot be violated (for that instance). Future writers may fail to follow the convention in their own new variables, but it takes only one person to rename. Sure you can use an add-on and "this-ify" variables, but you may have to do it again. It takes everyone doing it right, forever, 5 keystrokes at a time. With "better" devs maybe it's less of a problem but this added sense of betterness still costs. – Josh Sutterfield Feb 11 '21 at 00:49
  • Came here from google while searching for this. The link in this message takes you to a guide that now seems to indicate the exact opposite of what's in this answer. Now it says "Use camel casing ("camelCasing") when naming private or internal fields, and prefix them with _." at https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/coding-style/coding-conventions#camel-case – Kasuko Oct 11 '22 at 17:45
  • 1
    This seems to have changed as of December 2022. Now the recommended approach is: Use camel casing ("camelCasing") when naming private or internal fields, and prefix them with _. https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/coding-style/coding-conventions#camel-case – jward01 Dec 08 '22 at 19:10
  • @Phil `Throw_If_Customer_Is_Null` should probably be `...When_Customer...` (notice "when"). – Artur INTECH Feb 27 '23 at 11:44
16

The guidelines are summarized here http://blogs.msdn.com/b/brada/archive/2005/01/26/361363.aspx and include the stipulation to use "this." instead of underscore. But I find that peppering my code with "this."'s makes the code more wordy, cluttered and hard-to-read. Furthermore it seems to be less often followed than underscore so as a convention, "_" seems more conventional.

user316117
  • 7,971
  • 20
  • 83
  • 158
  • 1
    It looks like Microsoft didn't really ever follow their own guidelines, as weird as that sounds, seems like they used a mix of [`m_privateVar`](https://referencesource.microsoft.com/#System/net/System/Net/Sockets/TCPClient.cs,21) and [`_privateVar`](https://referencesource.microsoft.com/#mscorlib/system/collections/generic/list.cs,2765070d40f47b98,references) for private variables internally. – jrh Oct 26 '17 at 13:00
  • 3
    In the new docs: ["Internal and private fields are not covered by guidelines"](https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/names-of-type-members). – jrh Jan 24 '18 at 15:34
  • Using the underscore is simply a bad programming practice. 'this' primarily give you the full address of the variable. The underscore is not part of the language, it's a hack. StyleCop, as long as you don't mess with the default settings, will force yo to use it. Finally, it's trivial to use autocomplete with 'this', so it doesn't require any more typing than implicit variables. The only justification you have is that you got use to an arbitrary hack, so you think it's easier to read. – Quark Soup Apr 20 '23 at 20:00
2

With C# 7, we have a new use of underscore, indicating a "discarded" variable. This is common when using one of the TryParse methods -- we sometimes need either the return value or the out value, but not both. In C# 7, if you use "_" as the variable name, the compiler will optimize the object code to never create the variable at all. If you didn't need the output variable (you just wanted to know if the parse was successful) you might have a construction like this:

if (Int32.TryParse(input, out _)) 

Alternately, if you don't care about the parse success, only the output variable, you can assign that to _ like this:

_ = Guid.TryParse(input, out Guid id);

The underscore by itself is a legal variable name, so you can start using this pattern right away. Earlier versions of C# will just create a new variable with that name and not optimize the object code, but you will communicate to yourself and your fellow developers that the variable is unimportant to the function of your code.

Michael Blackburn
  • 3,161
  • 1
  • 25
  • 18
0

In ASP. NET MVC 3 underscores are used more usually. For example all your partial views you need to name with underscore like _MyPartialView.
It's going for easy distinguishing partial views and views in your application.

Anyway, in this example I don't prefer sing underscores, because there is no need to use them. It isn't wrong, because it's good practice to write with underline lists of your entities. But I will prefer to write without them.
So both ways are right, write in the way you feel more comfortable.

Chuck Norris
  • 15,207
  • 15
  • 92
  • 123
  • +1: oh i see. i am more of a webforms guy. thanks. but the code is framework agnostic here right? here a list and an instance have been given underscores. – naveen Mar 20 '12 at 06:15
  • Yes, in this example it's really framework-agnostic. See my edit. – Chuck Norris Mar 20 '12 at 06:18
  • `_MyPartialView` is strictly used with `.cshtml ` files to help indicate Partial Views in ASP.MVC - It is not the same as applying to variables – Piotr Kula Jul 20 '18 at 08:07