171

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?

Kev
  • 118,037
  • 53
  • 300
  • 385
TheCodeJunkie
  • 9,378
  • 7
  • 43
  • 54
  • 23
    The point of the underscore prefix, BTW, is not to deal with case issues. It's to be able to easily and visually tell fields and locals apart when reading code. I'll use it in C# and VB alike. – Neil Hewitt Jan 16 '09 at 12:34
  • 2
    @NeilHewitt: Well, it also prevents function parameters from conflicting with member variables, which require prepending every one of them with `this`, which sucks. EDIT: I just responded to a four year old comment... – Ed S. Jul 30 '13 at 02:31
  • Just for clarity the official standard is `_camelCase` (readonly favored) https://github.com/dotnet/corefx/blob/master/Documentation/coding-guidelines/coding-style.md – Chris Marisic Apr 08 '16 at 16:58

16 Answers16

346

IMPORTANT UPDATE (December 12, 2022):

It really doesn't matter which notation you use. Just go with what is already used at your project or pick whatever for a new one. At the end of the day it's nitpicking and has nothing to do with how productive you are. Being flexible is your most important quality! You are a mercenary and you have to fight with any weapon you get.

So do not read the rest as it's very opinionated. And being an extremist doesn't help.

Peace!

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.
Trident D'Gao
  • 18,973
  • 19
  • 95
  • 159
  • 1
    @1365 What about the case of naming a backing field for a property where you don't want to use a leading underscore. Ex: `Public int Foo{get{return _foo;}set{_foo=value;}}` and backing field `private int _foo;` What's standard way to name the backing field without the underscore? MS doesn't provide any guidelines regarding naming/casing of fields other than to not mark a field as public. – GisMofx Apr 22 '14 at 19:09
  • @1365 That's what I do, but just wondering. Also, I'm considering this statement from ms: _DO NOT assume that all programming languages are case sensitive. They are not. Names cannot differ by case alone._ In C# is ok, but their comment is if an there's some API that's external referencing your code that's not case sensitive. – GisMofx Apr 22 '14 at 21:13
  • 5
    Doesn't come from C++, because in C++ reserves identifiers beginning with an underscore for language and standard library usages. – Rob G Feb 10 '15 at 14:21
  • generated constructor has underscrore fields in vb.net (VS 2013). – toddmo Mar 10 '15 at 18:20
  • 1
    Why not use both `this` and underscore (`this._foo`)? The underscore ensures that there's no name clash between class variables and local variables. – Mas Oct 07 '15 at 12:53
  • I just followed your link to http://www.screenr.com/zDCH and it pointed out that screenr will be retired, and videos will be lost, in November. – Wai Ha Lee Oct 29 '15 at 09:40
  • 1
    @GisMofx As mentioned in [another answer](http://stackoverflow.com/a/450251/641833), foo starts with a lower case letter, so it should not be accessible externally, so only the Foo property would need to be accessible to non-case sensitive languages. – Trisped Feb 05 '16 at 20:56
  • 3
    An Official recommendation to use _ in C#: https://github.com/dotnet/corefx/blob/master/Documentation/coding-guidelines/coding-style.md (from @landoncz comment to http://stackoverflow.com/a/6773769/254109) – xmedeko Apr 08 '16 at 07:45
  • 8
    I disagree with nearly every single conclusion of yours regarding `this.` improving clarity and `_` reducing clarity. – Chris Marisic Apr 08 '16 at 16:49
  • @AlekseyBykov it's fine you can retaliate over internet points, my answer was right the entire time which is why it's part of the official standard. – Chris Marisic Apr 11 '16 at 13:42
  • 9
    Why do you distinguish between performance critical, multithreaded, system level code and other code? How is using `_camelCase` going to help me if my code is performance critical/system level code? – BornToCode Aug 04 '16 at 14:04
  • 2
    Guys from CoreFX team developed a convention that uses `_` to deal different aspects that have a lot to do with multi-threading and performance critical code. If your project doesn't involve multi-threading and performance critical code then the practices of CoreFX team might not be relevant. – Trident D'Gao Aug 04 '16 at 14:25
  • 17
    Using underscores has nothing to with writing performance critical, multi-threaded or system-level code. It's the consistency what matters and CoreFX team is just a team that agreed on a specific convention. This is a great answer, backed with a very nice analysis comparing naming conventions but I believe the added part saying "underscores are better because the CoreFX team says so" really lowers its quality. – Şafak Gür Nov 30 '17 at 16:32
  • it was a response to someone who made an example of CoreFX in comments – Trident D'Gao Nov 30 '17 at 17:26
  • 2
    I'm with @ChrisMarisic, I disagree with most of the arguments in this answer. 1. "underscore-notation clutters names" - I don't see how a single `_` character clutters more than the five characters of `this.` If your argument is that you only use `this.` when it's needed, then that goes to the next point: 2. "this-notation is consistent" - It's not if you only use it where it's really needed, in that case it's use is the definition of inconsistent. If you really want to use it in every situation, then that goes back to point 1. – Adam Goodwin Feb 08 '18 at 17:25
  • 1
    3. "underscore-notation requires you to keep an eye on `_` while refactoring, say turning a field into property" - you still have a similar problem with `this.`, because in either case if you're turning a field into a property you should capitalise the property name. You should never be changing a field into a property without thinking it through thoroughly, and if you're doing something thoroughly you should be considering naming convention at some point. – Adam Goodwin Feb 08 '18 at 17:29
  • 5
    Echoing the criticism of bizarre line that underscore is for "performance critical, multithreaded, system level code". It is fine to point out that the .Net Core team have gone all retro, violating the established company standard, but to suggest it helps when writing performance critical code is absurd. "Hey look, I use superfluous underscores and now my code is 20% faster!" – user603563 Mar 04 '18 at 12:05
  • you read it wrong, it says, IF you work on performance critical..., THEN you should use the underscore notation BECAUSE Core FX team does it, there is nowhere said that if you use the underscore notation then your code be fast – Trident D'Gao Mar 04 '18 at 19:41
  • 4
    I read it correctly, I was being appropriately sarcastic. Ok, so (a) If you work on perf critical... Yes I do; (b) then underscore because Core team does. The logic just doesn't work. Many .Net teams (most I've worked in) work on perf critical code without underscores. If the .Net Core team paraglide, should anyone working on performance critical code paraglide? It's simply a style choice one team made. You could indicate the different field types the Core team mention a number of ways without using an underscore. – user603563 Mar 04 '18 at 22:51
  • 1
    jeez, you are being inappropriately annoying, core fx team writes performance critical code and they use the underscore notation, this sets an example that shows that there is at least one case where it might be useful, if you are like core fx team you might benefit from adopting it, so what is exactly your problem? – Trident D'Gao Mar 05 '18 at 02:54
  • 7
    My problem is that I understand logical inference. https://en.wikipedia.org/wiki/Inference But hey, I get it's not for everybody. – user603563 Mar 05 '18 at 07:29
  • 2
    the C# Framework Design Guidelines book Naming Guidelines section 3.6.4 Naming Fields excludes private private fields. Jeff Prosise adds his insights and writes; "As a matter of personal preference, I typically prefix the names of private fields with an underscore (for example, _connection). When I read the code back after a time away, this makes it obvious to me which fields are not intended for public consumption. This convention is used quite a lot in the .NET Framework-for example, in System.Net.HttpWebRequest and System.Web.HttpContext-but it is not used throughout.". – Chris Morgan May 22 '19 at 15:54
  • All the given reasoning is just subjective. For clarity "this.name" forces me to visually ignore the "this" part. Probably thats fine for who is used to it. But for me is easier not-to-read an underscore than a complete word. For autocompletion, you can type "this" in any case, it will show also the underscored names. And it is not the common case to have lot of assemblies with tons of underscores when there is previously a good separation of concerns. I hope you're not trying to force your coalleagues to ditch the underscore with that kind of arguments. – zameb May 11 '21 at 13:38
  • 1
    [This](https://github.com/dotnet/runtime/blob/main/docs/coding-guidelines/coding-style.md) is the most updated coding style document for the dotnet team (last update 5 days ago). The one you have linked is to the CoreFx repo, which has moved to dotnet/runtime – spencer741 Sep 29 '21 at 04:55
75

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.

James Skemp
  • 8,018
  • 9
  • 64
  • 107
Dan Rigby
  • 17,133
  • 6
  • 43
  • 60
  • Is this a "just because we say so" kind of rule, or is there something that actually makes it bad to do so? The above rule description really doesn't say either. – peSHIr Jan 16 '09 at 18:10
  • 7
    It's mostly a "best practices" kind of thing. As the rule states, prefixing with "this" can be applied to any non-static member while prefixing with anything else **may** not be applicable due to language syntax rules. The "this" keyword makes the intended destination trivially clear. – Scott Dorman Jan 16 '09 at 19:08
  • 5
    I also favor the language's intended solution to the problem ("this") over artificial ways of getting around it. – galaktor Jan 13 '11 at 09:26
  • 12
    There's also a rule in the same software that says you shouldn't have two fields differing only in case. So what do you do with a protected variable wrapped by a public property? – Lilith River Oct 12 '11 at 10:41
  • 5
    My only problem with the 'no underscore' thing is that when programming against a (web)Form or such, using just 'this' doesn't help me at all filter down to those private fields I've defined and instead just gives me a gigantic list of the eight million other properties included with said object. –  Dec 07 '11 at 15:52
  • 18
    StyleCop seems to be saying that, if I consistently use `this` when referring to any class member, I could find all calls to all class members simply by searching for `this`. I can't argue with that, but I also can't think of a time where I needed to do that. The last thing I want to do is add tedium to coding and litter my code with `this` (which is *almost* Hungarian) for almost no practical gain. The fact is, if I'm looking at a line of code, anything that starts with a capital letter or an underscore is a class member, anything lower case is a local. – devuxer Feb 19 '12 at 02:06
  • 1
    @ComputerLinguist, it is acceptable to have members that differ only by case if only one of them is accessible outside the class (See CA1708 "This rule fires on publicly visible members only.") A protected field wrapped by a public property indicates a design problem for subclasses. Since subclasses may not have access to the source code of the superclass, they will not know the difference between the two members (unless it is documented, and in that case see "literate programming" and other commentary on the problem with capturing semantics in comments only. – Carl G Nov 02 '13 at 18:12
  • When you tell vb.net to generate a missing contructor (use the constructor before it exists, get the squiggly, then have it generate), it makes fields starting with underscore. VS 2013 – toddmo Mar 10 '15 at 18:17
50

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

Andreas Grech
  • 105,982
  • 98
  • 297
  • 360
Binary Worrier
  • 50,774
  • 20
  • 136
  • 184
  • 1
    Even though there'll be no effect, it's still a convention I'd be uncomfortable with - since it's a recipe for confusion if they differ only by case. It's just too easy to mis-read or mis-type if the only difference is the initial capital. – ChrisA Jan 16 '09 at 12:30
  • 2
    P.S. Personally, I don't underscore in C#. For me it's a personal preference, not a religious belief – Binary Worrier Jan 16 '09 at 12:32
  • 1
    I've done both ways and I wanted to make up my mind, one and for all, based on knowledge :P – TheCodeJunkie Jan 16 '09 at 12:35
  • 47
    I'm using underscores. It is easier to distinguish them from the arguments and local variables. – Rinat Abdullin Jan 16 '09 at 19:12
  • There's a good arguement for avoiding _varName in flavours of C and C++. many predefine symbols start with and underscore. This particular doesn't apply to most other languages, including VB and C# – Binary Worrier Jan 17 '09 at 16:40
  • 4
    I use _ only for private fields, however I almost never have private fields due to 3.5 auto property. Generally the only time I have a private field is if I implement lazy loading on non-primitive types. – Chris Marisic Jan 17 '09 at 21:16
  • _ has no usefulness at all. It's annoying to type and I don't like having to refactor code if I decide to make something public. I've never had any problems with just using pascal case everywhere in c#. – Brad Apr 18 '22 at 00:19
29

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."

M4N
  • 94,805
  • 45
  • 217
  • 260
  • 15
    Well I *always* prefix with 'this' no matter if I'm accssing a field, property or method. – TheCodeJunkie Jan 16 '09 at 12:34
  • 9
    For me, the underscore is sort of a shorthand notation of "this.". – M4N Jan 16 '09 at 12:35
  • 2
    In R#, the advice is to not call the parameter foo. Why not call it 'value' since you know it will be used to Set Foo ? – thinkbeforecoding Jan 16 '09 at 12:41
  • or you can name the parameter aFoo – Jacek Szymański Jan 16 '09 at 12:46
  • 17
    @Martin: The problem with underscore as a shorthand for "this" is that it can't necessarily be applied to all class members while "this" can. I think the code reads much easier/cleaner with the "this" keyword. In your example, the if (foo == x) will always refer to the parameter foo. – Scott Dorman Jan 16 '09 at 19:11
  • Updated the answer. Hope this makes a little bit clearer what I meant. – M4N Jan 16 '09 at 20:08
  • 4
    @TheCodeJunkie: Thats a whole lot of redundant characters in your code base. – Ed S. Jul 30 '13 at 02:33
  • 1
    @EdS. Naming a parameter useful is a lot of redundant code as well, you just retype this.connection every time why not _c...... – quadroid Oct 14 '15 at 10:33
  • @Console: I think you're attempting to be sarcastic... but perhaps failing. You can't seriously be comparing typing the redundant and value-less `.this` everywhere to good variable names. If you are, please, describe the benefits of the `this` qualifier to me. – Ed S. Oct 16 '15 at 07:33
  • 1
    @EdS. if this is valueless the underscore is as well. if you do not care about whether something is instance or not why add this information, it is worthless. But if you do care if something is instance or not use something that unmistakable indicates that you are dealing with an instance. which is why i use this and not a underscore (as i prefix my viewModels with viewModel not with VM) yeah it is redundant but every honk on this planet can figure out that it is not about a virtual machine, same goes for this. – quadroid Oct 16 '15 at 07:38
  • 1
    "if this is valueless the underscore is as well" - No, it's not... it prevents name clashes all over the place. Seems you're just a fan of extra typing. – Ed S. Oct 16 '15 at 18:02
  • @EdS. this does prevent naming clashes as well while you can omit it 95% of the time. where you have to add a worthless(and ugly) underscore everywhere in the class even if it does not provide any value on 95% of the places. – quadroid Oct 20 '15 at 09:15
  • 1
    @Console: I think your 95% number is completely made up. Look, I don't really care to argue this with you. You don't like it? Fine, don't use it. It's subjective and I really don't care. I wouldn't want to work on your code with all of your `this.` nonsense all over the place, and you wouldn't like my `_`'s. Great, c'est la vie. – Ed S. Oct 20 '15 at 17:43
  • this problem is not specific to private properties tho. this.publicFoo is exactly the same. If its not ok for private it shouldn't be ok for public either and visa versa. – Brad Apr 18 '22 at 00:24
  • I know it's been several years, but my two cents: `this.` is better than `_` because the compiler enforces it. There's nothing _forcing_ a field that starts with underscore to be a member, whereas `this.` cannot be anything but a member. – Charles Wood Aug 08 '22 at 17:38
20

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.

Chris Marisic
  • 32,487
  • 24
  • 164
  • 258
  • 21
    The `this` keyword is a guaranteed reference to the current object. You don't get that with an underscore. No need to loathe `this`. – Jason S Sep 08 '11 at 21:37
  • 16
    Why invent a 'standard'. 'this.' tells you the object is an instance variable 'Class.' tells you it's a class varible. Everything else is a stack variable. The underscore belongs on the same pile of bad ideas where Hungarian Notation now decomposes. – Quark Soup Mar 22 '13 at 20:01
  • 6
    @DRAirey1 too easy to miss the this. when you need it and you end up doing weird things with state. – Chris Marisic Mar 23 '13 at 00:05
  • 2
    @ChrisMarisic It's only too easy to miss if you aren't in the habit of doing it. It's no different than forgetting to put an `_` in front of a member field. Once you've done it for awhile, you'll make habit of always marking your member fields with `this.` ReSharper's `remove redundant this keyword` is only adding to the problem. The official C# naming guidelines explicitly forbid using underscore anyways. As others have said, `_` reaks of Hungarian Notation. Get in the habit of using `this.` to mark field members and you will find that it's not so easy to miss when you are the composer. – crush Oct 25 '17 at 03:22
  • 1
    @crush the standards are to underscore in 2017, that ship sailed somewhere around 2012-2015 with the machinations with .NET Core. Go look at Core repos from Microsoft and you'll see underscored fields. – Chris Marisic Oct 25 '17 at 16:37
  • @ChrisMarisic I think the other answers here have citied significant documentation to refute the claim that "that ship sailed somewhere around 2012-2015". The official guidelines for the C# language say otherwise. The StyleCop documentation says otherwise. The .NET Core guidelines talk specifically about using underscores only for specific cases. When they update the actual standards doc, you can claim the standards are to underscore. Also note that the workings of the CoreFX team does not reflect on the entire Microsoft organization or the C# language designers. – crush Oct 25 '17 at 23:09
  • @crush there's no statement in the world that could change my mind. "Sun will go supernova if you underscore a field?" _blackhole = true – Chris Marisic Oct 26 '17 at 15:11
  • 4
    @ChrisMarisic You are of course welcome to your opinion on the usage of `_`, but don't posit it as established standard when it clearly is not. – crush Oct 26 '17 at 15:46
  • 4
    I lost you at "I went on to create my own style". – rory.ap Jan 17 '18 at 20:44
  • I don't get it. You misread the field as a variable, but did you understand what the code was supposed to do, or not? – Thomas Eyde Nov 27 '19 at 08:26
18

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; }
    }
}
Lance Fisher
  • 25,684
  • 22
  • 96
  • 122
  • 44
    public string FirstName {get; private set; } – jason Jun 05 '09 at 15:07
  • 3
    You can still use the lowercase as the method parameter, by using the `this` keyword. Making that a mute point in the ongoing and always controversial "to underscore or not": `public MyClass(string firstName){ this.firstName = firstName; }` – mateuscb May 23 '15 at 03:37
  • 5
    It's the future, now just `public string FirstName { get; }` and the setter is still available in the constructor – Chris Marisic Apr 08 '16 at 16:53
  • In this example. `this` would only be necessary in the constructor. No need to use it anywhere else. So `firstName` as the field name works very well. – Thomas Eyde Nov 27 '19 at 08:28
10

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?

peSHIr
  • 6,279
  • 1
  • 34
  • 46
  • 5
    For me the _ clutters up the _words when quickly _scanning through code, it becomes less like just reading _and _more _like having to stop at _every _ to acknowledge it and _realize it's _not a control character of some _sort. It also disrupts indenting by practically pushing the first useful character in field names one column to the right. I generally dislike C++ because most C++-programmers tend to write incredibly terse and slow-to-read symbol/machine-like code and I simply prefer not having that in C# code :) – Oskar Duveborn Nov 14 '13 at 15:56
  • 32
    For me, the this. clutters up the this.words when quickly this.scanning through code, it becomes less like just reading this.and this.more this.like having to stop and this.every this. to acknowledge it and this.realize it's this.not a control character of some this.sort. I would much prefer to find the occasional `_fieldFoo` or `_fieldBar` than to have my usage cluttered up with `this.fieldFoo` or `this.fieldBar`. I find the `this.` prefix to be much more jarring than a leading underscore. – AggieEric Dec 15 '13 at 01:21
  • I was thinking perhaps this discrepancy in experience might stem from oldschool filesystems or file transfer protocols where spaces weren't allowed which trained some users into seeing underscores as spaces and therefore not distracting their reading. Me on the other hand have issues with such filenames as I always used spaces in my own filenames from the beginning... – Oskar Duveborn Feb 28 '14 at 10:58
  • 3
    @AggieEric hit the nail on the head there. Just reading his sentence gives me a head-ache! I tried to stick to MS recommendation for years in this matter, and I got so SICK of reading little blue `this` words everywhere, I made a nerd-rage decision right there. Now, I religiously use `this` for property references ONLY, or when I need to explicitly distinguish between `this` and `base`. Each to his own, I guess :-) – Riegardt Steyn Oct 13 '14 at 10:43
  • @Heliac: You're just confused because you probably read out "this", and not "_". If you do have to communicate the fields in spoken language, "this" is much shorter than "underscore". – DanMan Mar 18 '15 at 10:53
  • 1
    I think it is because, ultimately, starting anything with a punctuation character hurts readability. It doesn't seem to bother everyone but to me it feels very unnatural reading anything that starts with punctuation. The more like English the code is, the easier I find it to read. And with modern IDEs it is drop dead simple to tell the difference between locals and private members because they'll most likely be different colours. – Tim Long Jun 05 '16 at 00:55
  • @TimLong I feel the exact same way. Any `this.` or `_` or `m_` removes the english reading ability for me. I also strongly agree with the colors for differences with parameters/fields differentiation and in the past 15 or so years have never had a name collision issue because of it. Also IDEs will warn if self referencing happens too. – Water Nov 08 '19 at 03:51
7

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.

Rahul
  • 2,431
  • 3
  • 35
  • 77
6

Style Cop recommendation or not, digging into the .NET Framework shows a lot of "_" usage for member variables. Whatever the creators of Style Cop recommend, it's not what majority of the MS employees are using. :) So I'll stick with the underscore. Because I personally make a lot less mistakes using the underscore then the this (example: using varName = varName instead of this.varName = varName, it's really stuck in me)

Michel Bakker
  • 153
  • 2
  • 5
4

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.

jcollum
  • 43,623
  • 55
  • 191
  • 321
  • 16
    It's hardly a valid critique of a naming convention to say that it's possible for developers not to follow it. – Robert Rossney Jan 16 '09 at 18:22
  • 14
    Wow, your definition of “easy to break” and mine are, like, complete opposites. Yours means “easy to break intentionally,” while most other people probably mean “easy to break *accidentally*.” I’ll leave it as an exercise to the reader to figure out which one is more relevant in writing readable code … – Konrad Rudolph Jun 05 '09 at 15:06
  • 9
    @Konrad: You sound pretentious when you say "as an exercise to the reader". This isn't a math textbook. – jcollum Jun 08 '09 at 16:53
  • 4
    Slightly less negative now :) While we may be rowing against the current, I also dislike the underscore convention. In my view it is no different to Hungarian notation and to be honest, it makes my eyes bleed (hurts readability). We threw Hungarian Notation out with C# and it's time to excise this last vestige of not trusting your IDE. – Tim Long Jun 05 '16 at 00:49
  • 2
    I heard that MS actually says that the underscore is not to be used in its C# style guide. https://blogs.msdn.microsoft.com/brada/2005/01/26/internal-coding-guidelines/ -- section 2.6 -- looks like Brad Abrams agrees with us at least! – jcollum Jun 05 '16 at 14:56
  • 2
    Oh no, `this._NOWwhat = 1;`? – Maiku Mori Mar 30 '18 at 00:48
  • 1
    The reason the underscore is used to much is that Microsoft itself uses it in its code. Thats because a lot of Microsoft developers are C++ developers and they use this by convention. The programming guide of C# is clear about this and the underscore should not be used for prefixing private variables but the this keyword should be used to distinguise between them. – Herman Van Der Blom Feb 26 '19 at 08:28
  • @HermanVanDerBlom is there any observed convention in C++ for leading underscores to denote class membership or encapsulation? If anything, Hungarian notation (i.e. `m_`) was still prevalent when C# was being developed. I've never seen this; a leading underscore may however be used to denote global scope (i.e. gcc) or a reserved preprocessor macro (i.e. in MFC/ATL). – Rab Mar 18 '21 at 11:06
  • I think its the same as C#. The underscore or m_ are redundant. With an underscore or m_ you are explicitly declare the variable a private class variable. Implicitly its already a private class variable that can be accessed with this. If you define a private variable you know its private to that class and belongs to that class. So if you want to get access to those variables you can do that with ""this". So its just knowing the language well. Its even the same now for Javascript with classes. – Herman Van Der Blom Mar 19 '21 at 12:28
3

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.

Robert Rossney
  • 94,622
  • 24
  • 146
  • 218
  • The C# gang appears to agree with you with the newish private int foo {get; set;} syntax sugar. – Dana Jan 16 '09 at 18:47
  • Oh, sure; what I'm describing here is totally unworkable without that. – Robert Rossney Jan 17 '09 at 01:07
  • What you're describing is "Auto-implemented properties". Unfortunately, with Visual Basic.NET, this actually uses a "hidden" _prefix variable behind the scenes i.e. if you had an auto-implemented property "Public Property Foo As Integer", you could then NOT have the member variable declaration "Private _foo as Integer" –  Jan 19 '12 at 08:21
  • 1
    No, I'm not describing auto-implemented properties, at least not in my example. I'm describing a scoping level that doesn't exist in C# or VB. It's really unfortunate that VB chose such a trivial way to munge the names of backing fields. C#'s is ugly enough that you wouldn't ever create a variable with the same name by accident. – Robert Rossney Jan 24 '12 at 07:04
1

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).

Frederik Gheysels
  • 56,135
  • 11
  • 101
  • 154
0

There are no implications whatsoever. When your code is compiled, all that is important to the compiler is the field/property's namespace and visibility. An underscore is just as significant as any other character when naming an identifier. The real trick is to use a convention that you and the people around you will understand.

0

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#.

Rob Windsor
  • 6,744
  • 1
  • 21
  • 26
0

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>();
        }
Tim Lovell-Smith
  • 15,310
  • 14
  • 76
  • 93
0

Update 2023

According to Microsoft naming rules and conventions(the above link seems to updated): Use camel casing ("camelCasing") when naming private or internal fields and prefix them with _.

Naod Agere
  • 39
  • 1
  • 6