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?
8 Answers 8
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.
-
1I 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– Joel C2011年08月15日 20:22:21 +00:00Commented Aug 15, 2011 at 20:22
-
@Joel - You're correct. This question deals with it: stackoverflow.com/questions/1195030/…dave– dave2011年08月15日 21:02:31 +00:00Commented Aug 15, 2011 at 21:02
-
2I still use the "m_" prefix...CesarGon– CesarGon2011年08月16日 10:05:07 +00:00Commented Aug 16, 2011 at 10:05
-
5+1 "for you do not have to do everything that MS tells you to do". Think for yourselves!gbjbaanb– gbjbaanb2011年08月16日 11:39:32 +00:00Commented Aug 16, 2011 at 11:39
-
1It's only not CLS-Compliant if the field is
protected
, notprivate
Rachel– Rachel2011年08月17日 14:12:32 +00:00Commented Aug 17, 2011 at 14:12
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.
-
2Nice 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 forthis
. Is it because it is misunderstood?Jason S– Jason S2011年12月06日 23:14:48 +00:00Commented Dec 6, 2011 at 23:14
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.
-
To elaborate a bit on
this
, I always preferthis
, 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 bythis
. 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– Jason S2011年12月06日 23:31:33 +00:00Commented Dec 6, 2011 at 23:31
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.
-
4Would you care to summarise for those of us who don't own the book?Kramii– Kramii2011年08月16日 05:52:34 +00:00Commented Aug 16, 2011 at 5:52
-
I agree with Kramii. A summary would be great!Vaccano– Vaccano2011年08月16日 18:09:59 +00:00Commented Aug 16, 2011 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– Tangurena2011年08月16日 19:39:46 +00:00Commented Aug 16, 2011 at 19:39
-
1lol, 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– gbjbaanb2013年07月20日 22:38:40 +00:00Commented Jul 20, 2013 at 22:38
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
.
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_
.
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
-
2Yes, but MS deprecated use of the m for members which is what the OP is getting at.Christopher Bibbs– Christopher Bibbs2011年08月15日 18:55:57 +00:00Commented Aug 15, 2011 at 18:55
-
"Most companies" does not include Microsoft, which is the company that this question is about.Aaronaught– Aaronaught2011年08月15日 18:58:34 +00:00Commented Aug 15, 2011 at 18:58
-
1I didn't realize that Micrsoft MSDN is for internal coding standards at Microsoft.JeffO– JeffO2011年08月15日 20:12:48 +00:00Commented Aug 15, 2011 at 20:12
-
1@JeffO: You're right, it's not, but their internal coding guidelines say the same thing.Aaronaught– Aaronaught2011年08月15日 21:31:30 +00:00Commented Aug 15, 2011 at 21:31
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).
-
11) Hungarian was not invented by Microsoft, and 2) the "Hungarian" you're referring to is type Hungarian rather than semantic Hungarian.Aaronaught– Aaronaught2011年08月15日 21:29:37 +00:00Commented Aug 15, 2011 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– JaCraig2011年08月16日 16:23:02 +00:00Commented Aug 16, 2011 at 16:23
-
[citation needed]Aaronaught– Aaronaught2011年08月16日 21:04:59 +00:00Commented Aug 16, 2011 at 21:04
-
1Um 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– Aaronaught2011年08月16日 22:39:04 +00:00Commented Aug 16, 2011 at 22:39
this.
.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.