20

I asked this question quite some time ago: How do you name your private variables in C#?

In one of the answers, I was pointed to Microsoft's MSDN page that shows that private variables/fields should be named like this:

private int myInteger;

But a parameter would be:

void SomeMethod(int myInteger)

and a local variable would be like this:

int myInteger;

So when you reference them like this

myInteger = 10;

you have no way of knowing which one you are talking about.

I am now starting a new project and one of my co-workers is asking me why we don't do something to differentiate at least some of these.

I am wondering the same thing. Why didn't Microsoft's standard keep these different?

Vaccano
  • 4,028
  • 5
  • 31
  • 37
  • 10
    What do you mean "you have no way of knowing which one you are talking about"? Of course you do - scope. – Thomas Owens Aug 15 '11 at 18:46
  • 3
    That guidance seems outdated, the resharper default (which has become something of a defacto style guide) recommends prefixing private fields with an underscore which is what I'd always done anyway. –  Aug 15 '11 at 18:49
  • 25
    @kekekela: It's absolutely not outdated; StyleCop will explicitly flag any instances of member variables beginning with an underscore. Frankly I find the underscore pointless and annoying because the casing conveys the exact same information. If you need to make the scope explicit, then prefix assignment with `this.`. – Aaronaught Aug 15 '11 at 18:56
  • 13
    @Aaronaught I find a bunch of redundant "this." scattered around my code pointless and irritating. –  Aug 15 '11 at 19:07
  • @kekekela - you understand and are willing to think about the scope you're using. The op's cow-orkers are apparently not. – DaveE Aug 15 '11 at 19:32
  • 13
    @kekekela: The only place I *ever* find myself having to do that is in the constructor, and in the constructor it makes perfect sense because you are literally passing in the values that initialize the member fields (`this.component = component`). If you find yourself with ambiguous scopes elsewhere, such that you have "a bunch of redundant 'this.' scattered around your code", then you have poorly-written code. – Aaronaught Aug 15 '11 at 21:27
  • Can't speak as to why Microsoft made that decision, but we *used* to prefix all parameters with `a` (or `an`) to keep them distinct. Have abandoned this practice as too many tools (including Resharper, fxCop/CodeAnalysis, StyleCop) complained - the false positives were swamping the useful messages. So we switched. Still use a `m` prefix for members though. – Bevan Aug 17 '11 at 04:13
  • @kekekela I find underscore ugly, redundant and not exact. It is a convention that could be misused whereas `this` definitely refers to the current instance. – Jason S Dec 06 '11 at 23:08
  • 2
    @kekekela and the others who voted up the comment - it is the underscore and `_m` instance variable naming conventions that are redundant. `this` is NOT redundant. `this` always refers to the current instance. It is a keyword that has been there since the start of .NET and it won't be going away. These underscore naming conventions come and go and every shop uses a different one. **They** are redundant, since you have `this` (which you can use judiciously). – Jason S Dec 06 '11 at 23:46
  • 2
    using 'this' is either redundant (since its referring to the same scope it would otherwise) or shit code (since you're having to use it to disambiguate between two inscope variables with the same name) –  Dec 11 '11 at 03:37
  • 3
    "It's absolutely not outdated; Stylecop..." Yeah, if you think StyleCop is a good tool we're probably not going to have much common ground but to each his own... "If you need to make the scope explicit , then prefix assignment with this." If you need to make scope explicitly you're just writing bad code (even if you just do it in constructors.) –  Dec 11 '11 at 03:46
  • @user29776 just because you don't need `this.` to _read_ the code doesn't mean it's not helpful to _write_ the code. It 1) reduces the pool of Intellisense suggestions (without the cognitive clutter of irrelevant close matches outside scope), 2) starts working off 1 character (`this.i`), 3) and can jumpstart your brain by letting you scan through a list of local members. So...not pointless. – drzaus Nov 17 '14 at 17:19
  • 1
    Just find it hilarious how people say `this.` is redundant and ugly and they dont want to see it scattered arrond everywhere in their code, but are totally willing to put an `m_` or just the underscore in front of EVERY usage of the private field to scatter it everywhere. Sorry but this just doesn't make sense. But some good reasons also: underscore is not CLS compliant. Further the underscore is added only to private fields. Not private methods. I cannot see how "logical" thinking people prefer it this way. Further code scattered with random underscores is less uniform and less readable. – Chris Dec 17 '19 at 11:39

8 Answers8

16

The original naming conventions had a m_ prefix for class members, this got reduced down to simple an underscore. You'll see a lot of older C# Microsoft code using an underscore prefix. However, I heard in a Tech Ed once that a leading underscore is not CLS compliant. I assume this is the reason why they moved to the simpler one-name-fits-all scheme. It used to be (not sure now) that VB.Net's case insensitive names were also not CLS compliant.

For what its worth, I still use the leading underscore for class members. Even though you can disambiguate using this (this.name as opposed to name), bugs still get through.

You do not have to do everything that MS tells you to do.

dave
  • 2,466
  • 15
  • 21
  • 1
    I think you've confused "CLR-compliant" with "CLS-compliant". If something were non-CLR compliant, it wouldn't compile. CLS is just a warning that it may not be compatible with other languages, and basically only affects public members (technically, things visible outside of your assembly). – Joel C Aug 15 '11 at 20:22
  • @Joel - You're correct. This question deals with it: http://stackoverflow.com/questions/1195030/why-is-this-name-not-cls-compliant – dave Aug 15 '11 at 21:02
  • 2
    I still use the "m_" prefix... – CesarGon Aug 16 '11 at 10:05
  • 5
    +1 "for you do not have to do everything that MS tells you to do". Think for yourselves! – gbjbaanb Aug 16 '11 at 11:39
  • +1: And the tooling in Visual Studio helps you know what's what anyway. – Ryan Hayes Aug 16 '11 at 22:40
  • 1
    It's only not CLS-Compliant if the field is `protected`, not `private` – Rachel Aug 17 '11 at 14:12
10

local and parameter variables are named the same way because their scope is the same

As for private variables, there are different opinions on that. I've always used the standards found here, which specifies to use a leading _ before private variables, although the author does say that the _ is a bit controversial and that Microsoft recommends against it.

Wikipedia states that in C and C++

Names beginning with double underscore or an underscore and a capital letter are reserved for implementation (compiler, standard library) and should not be used (e.g. __reserved or _Reserved).

so perhaps that was the reason behind Microsoft recommending against that, although it is fairly well known that many Microsoft devs use an _ prefix for their private variables anyways.

Rachel
  • 23,979
  • 16
  • 91
  • 159
  • 2
    Nice point about parameter and local variables having the same scope (+1). No-one else mentioned that. The corollary being that if you need a local variable with the same name as the parameter, you can just use the parameter. Personally though I find underscore ugly and imprecise. Whereas `this` definitely refers to the current object. I don't understand the hatred for `this`. Is it because it is misunderstood? – Jason S Dec 06 '11 at 23:14
4

I can't tell you for sure why they didn't keep them different. It's likely that nobody can unless someone who took part in creating the standards happens to see this question.

Many people create their own conventions by prefixing instance variables with _ or m_, but I really don't think it matters. You can infer a lot from context and IDEs these days are smart enough to help you out. Visual Studio with the ReSharper addon, for example, will show you local variables and instance variables in different colours.

If it really matters that you differentiate between the two scopes, you can use the this. prefix to refer to the instance variable:

public class Test
{
    private int myInteger;

    void SomeMethod(int myInteger)
    {
        this.myInteger = 10; // sets instance variable to 10
        myInteger = 10; // does not affect the instance variable.
    }
}

Without any other plugins, Visual Studio will by default help you with Intellisense:

screenshot

(The pop-up may still be styled by ReSharper there, but ReSharper doesn't add anything to the features of built-in Intellisense, so while the stock one might look a little different, it'll still have both options in there.)

You can also use code analysis tools like FxCop and StyleCop to help you catch potential problems with variable naming and scope.

Adam Lear
  • 31,939
  • 8
  • 101
  • 125
  • To elaborate a bit on `this`, I always prefer `this`, because it definitely refers to the current instance whatever house you're at, so it is precise. The underscore or underscore m conventions are just that - conventions that may or may not refer to instance variables and they are made redundant by `this`. The only place I see underscore useful is in case-insensitive VB to distinguish object and class names. But that is a whole other story. – Jason S Dec 06 '11 at 23:31
4

Why didn't Microsoft's standard keep these different?

The folks at Microsoft wrote a book called Framework Design Guidelines which explained a number of conventions, including why some things were camel cased, and others were pascal cased.

Edit (adding details from the book):

In the book, they mention doing usability studies, as well as some of the lessons-learned from acquiring the Turbo Pascal group. Also, while not all languages are case-sensitive (such as VB), others are (such as C#), so one should be consistent in one's naming. One cannot depend upon differences in case alone to distinguish items. If one sticks to the conventions used by the rest of the framework, it will lead to less confusion by devs.

Chapter 3, Naming Guidelines.
Section 3.1 is capitalization conventions.

camelCasing is for parameter names.
PascalCasing is for namespace, type and member names. In the event that there are 2-letter acronyms as part of the name, keep them capitalized together, such as IOStream.

Section 3.5 covers naming classes, structs and interfaces.
Section 3.6 covers naming type members.
Section 3.7 covers naming parameters.

Tangurena
  • 13,294
  • 4
  • 37
  • 65
  • 4
    Would you care to summarise for those of us who don't own the book? – Kramii Aug 16 '11 at 05:52
  • I agree with Kramii. A summary would be great! – Vaccano Aug 16 '11 at 18:09
  • @Kramil, Vaccano, It looks like I'll have to check it out of the library again. Normally I only do so when starting a new job and discussions turn to naming and coding standards. – Tangurena Aug 16 '11 at 19:39
  • 1
    lol, so "One cannot depend upon differences in case alone to distinguish items", then goes on to say use camelCase or PascalCase to differentiate items. – gbjbaanb Jul 20 '13 at 22:38
1

Because they are pretty distinguishable as they are depending on the context they are written in.

For example, have you ever used a parameter as a member variable? Or a local variable as a parameter? How about a member variable as a local one?

  • All member variables are in the "body" of a class. I really don't buy the argument that you need to prefix the member when you can use this to distinguish it from a local variable with a similar name, otherwise it's not needed.

  • A local variable is also only defined inside a method's scope or a in code block scope.

  • A parameter is always defined in the method signature.

If you get all of these types of variables confused or mixed together then you really should be thinking more about your code design to make it more readable or discoverable. Give them better and more self descriptive names than myInteger.

Spoike
  • 14,765
  • 4
  • 43
  • 58
0

I can't answer your question about Microsoft's standards. If you want a standard to differentiate these things, the standard I use for PL/SQL parameters is prefixing the parameter name with in_, out_, io_, for in-, out-, and in-out- parameters. Variables that are local to a function are prefixed with a v_.

FrustratedWithFormsDesigner
  • 46,105
  • 7
  • 126
  • 176
0

Most companies I know have coding standards that specify either an underscore or the lowercase letter m (for "member" I assume) as a prefix for their member variables.

So

_varName

or

mVarName

ElGringoGrande
  • 2,913
  • 22
  • 20
0

Just as other people have pointed out, you can usually tell which is which by the scope that the item is used. You actually can't have the parameter and local variable in the same scope and if you want the private variable, just use this.myInteger. So I don't think Microsoft worried about it too much as you can easily differentiate between them if you want.

But that being said, I'm a bit surprised that no one has said this yet, but forget about Microsoft and their naming conventions (well someone might have said it by now as I had to run to a meeting and left this open without submitting it). Hungarian notation was also a naming convention started at Microsoft (or was it Xerox? I can never remember when Simonyi came up with it). I can't think of anyone that I know that doesn't curse the name of Hungarian notation to this day. We became so annoyed with it at the place that I worked that we came up with our own standard that we used internally. It made more sense to us and sped up our work a bit (it was actually pretty close to what Microsoft suggests now, but everything was pascal case with the exception of private variables).

That being said, the newer standard that Microsoft uses (the mixture of camel case and pascal case) isn't too bad. But if you and your coworkers don't like it, come up with your own set of standards (collectively is best). This of course depends on whether or not your company has a set of standards already. If they do, stick to them. Otherwise come up with what works for you and your coworkers. Just keep it logical.'

Since Aaronaught asked for citation about Charles Simonyi and Hungarian Notation: http://en.wikipedia.org/wiki/Charles_Simonyi

http://en.wikipedia.org/wiki/Hungarian_notation

http://msdn.microsoft.com/en-us/library/aa260976(v=VS.60).aspx

http://ootips.org/hungarian-notation.html

http://www.hitmill.com/programming/vb/Hungarian.html

http://web.mst.edu/~cpp/common/hungarian.html

Last two are just examples of Hungarian notation and the ootips link is just some quotes concerning some opinions on the subject. Note that there is also system Hungarian Notation but that also, as far as I'm aware, came to popularity from Microsoft programmers (although unlike Simonyi for the apps variation, I don't know whom).

JaCraig
  • 197
  • 3
  • 1
    1) Hungarian was not invented by Microsoft, and 2) the "Hungarian" you're referring to is type Hungarian rather than semantic Hungarian. – Aaronaught Aug 15 '11 at 21:29
  • I never said that Microsoft came up with it. I actually said Charles Simonyi came up with it (specifically apps hungarian notation). Microsoft pushed it heavily, but I never said they created it (in fact I said I wasn't sure if he created it during his Xerox or Microsoft days). I was giving it as an example of something that a large company (Microsoft) suggested as the way things should be done. My point in all of this is the OP shouldn't worry about naming conventions that a company that he doesn't work for says is the "right way" (unless he works for Microsoft, in which case he should care). – JaCraig Aug 16 '11 at 16:23
  • [citation needed] – Aaronaught Aug 16 '11 at 21:04
  • 1
    Um yeah, we didn't need a citation on what Hungarian notation is. The [citation needed] is for all of the dubious claims in your answer. – Aaronaught Aug 16 '11 at 22:39