Underscores in private fields


In the naming guidelines it’s clearly stated:

✗ DO NOT use underscores, hyphens, or any other non-alphanumeric characters.

Yet I see commits which sole purpose is to introduce such formatting changes. (those are 4 different commits to introduce the formatting changes).

They all seem to apply:

  • Underscores for all private instance field names
  • s_ for all private static field names
  • t_ for all private thread static field names

Should the guideline docs be updated or those commits be reverted? I kinda like NOT having to use underscores all over, so I prefer the previous style better, for what it’s worth :wink:

Foreign language and non-ASCII submissions

The guidelines also state:

✗ DO NOT use the Hungarian notation.

so s_ and t_ fail there too. (although of course there is the I and T typing prefix exclusions…)

In Java the convention for static types is ALL_CAPS_WITH_UNDERSCORES (at least for constants - and since mutable shared is somewhat dangerous…). I don’t know if a similar guideline should be explored/adopted here.


Yes, Core .NET conventions seem to be wierd for me.
I would take StyleCop default naming conventions.
Or ReSharper default naming conventions.


@kzu I think you missed the key paragraph in the naming guidelines:

Casing and naming guidelines apply only to public and protected identifiers, and privately implemented interface members. Teams are free to choose their own guidelines for internal and private identifier

Looks like the corefx team did exactly that and decided they want to use underscore prefixes for private fields.


C# code should look like C# code, which means, following the design guidelines.

I don’t care that some people are still attached to whatever languages/practices they used in the past, specially when they don’t know why they used it and why they aren’t needed in C#.


…that might be in there (and I missed it too), but I’d actually argue against it. I think it would be better to have consistent conventions even for internal, private use. For one thing, it cuts down on cognitive load when switching between working on libraries. Nothing like swapping from something that decided to use Hungarian Notation, designating s_ for shorts, going to this…
I’m not sure how necessary that t_ prefix even was, because it’s the only static field in that class (ie, you’re not differentiating between different uses of something. I suspect that if you were attempting to differentiate between thread and global static in the same class, you probably have a design problem)


I’ve commented on one of the commits (https://github.com/dotnet/corefx/commit/3251c1cae5860785cfb716d3822d11149a88e0fa) and Immo replied.


I did too. For what it’s worth, quoting myself here:

I can understand that @davkean and team have been coding since way before a great IDE even existed to edit C# code, but every version of Visual Studio (back to VS2010 as far as I can verify right now) has provided refactoring, “generate from usage” code expansion and code snippets that do not use underscores. That’s as much of a public official guideline as it can get.

Having different teams within Microsoft not follow their own IDE guidelines is not only weird, it forces anyone contributing to more than one Microsoft OSS project (i.e. Rosyln AND CoreFX) to constantly remember to change what the IDE already generates by default so that it matches alternating coding styles.

I can only imagine how annoying that would get really soon…


i firmly believe all private fields should be named with underscore as a prefix. the “this” keyword absolutely appals me when it is used for nearly any purpose whatsoever other than “this.GetType()” for reflecting.

c# is quite happy with both “this.foo = foo” and “foo = foo” it is far too easy to accidentally miss assigning to the field. also if you do not prefix fieldnames you now risk collisions with local variables and with parameters.

also the underscore prefix has become nearly universally accepted to mean private. this alone is an ultimate reason to use underscores.


Ignoring setters (which in C# should generally be done with properties anyways, and autoproperties don’t want to be named differently), collisions with local variables and parameters may mean you should rename something. Or possibly extract a method, to limit the scope of a name.
Prefixing in general is problematic, often because it ends up becoming noise. Underscores in this case are “good” Hungarian notation (use), but even that’s no longer necessary with IDE support, or keeping method length short (or modifying scope via extracting to static/anonymous methods)

Personally, I would prefer not having an underscore prefix. Really, though, I would far rather have a standard that governed internal library code too.


I like coherence. The underscore prefix lacks it. And so do your reasoning, @dotnetchris.

There’s absolutely no reason whatsoever to use “this.GetType()” over just “GetType()”. But you do have to use “this” for onw indexers, and there’s no way around it.

As to the underscore being “nearly universally accepted”, it depends on the crowd you hang out with. And this alone is a reason to question it.


I mean truly universal, as in across nearly every language in modern usage.


Would you care to give examples?

I suppose the Roslyn code doesn’t count, right?


From Microsoft themselves, via MSDN:

X DO NOT use underscores, hyphens, or any other nonalphanumeric characters.
X DO NOT use Hungarian notation.

This is meant to be for .NET Framework code in general, so no just C#


The default coding conventions for Java say no.
In fact, the Oracle guidelines (although they appear to be no longer maintained) explicitly disqualify underscores altogether (and dollar sign, $, as a leading character). Default checks for Checkstyle (the Java equivalent to StyleCop/FxCop - can you tell I used to be/am a Java programmer?) also disallow underscores.


Using this code:

var _x = "test";

in JSLint gives this output:

Unexpected dangling ‘_’ in ‘_x’.


Well, I just want to give my 2 cents on this thread, and I also believe that all fields should not have underscores as leading character.

C# has a “this” keyword that serves exactly the purpose to assign a method’s parameter to a field when they have the same name, so it seems like the use of underscore partially defeat the purpose of “this”.
A language’s keyword should be preferred among a simply naming convention.

Moreover, It feels like for as C# was designed (and also the main IDE well-featured) there’s really no need to use any Hungarian notation or other convention to better clarify a variable’s scope. These leading underscores sounds like unneeded garbage, to me. :))


Underscrores should be used in private name fields. Better with s_ or m_ prefix.

Isn’t it?


Initial underscores have a practical advantage, in that not only do the naming conventions prohibit them from public or protected names, but such names are not CLS compliant. An accidentally visible private (not very likely in itself, but can happen from a change for an investigatory experiment that doesn’t get undone) will hence cause warnings if the assembly is CLS compliant.


You excerpted only part of the MSDN documentation. You left out the part that says it does not cover privates…

“the field-naming guidelines apply to static public and protected fields. Internal and private fields are not covered by guidelines,”

.NET Foundation Website | Blog | Projects | Code of Conduct