On Hungarian notation for instance vs. static fields naming

If there is a topic I disagree with most fellow programmers, it is about instance and static fields naming guidelines. Call me old-school, but I am prefixing them with m_ and s_, or in others word I am doing Hungarian notation on fields naming. But clearly, the global consensus can be read on the MS Developer static field naming guideline:

  • Do not use a Hungarian notation prefix on static field names.

On the wikipedia Hungarian notation entry, there are two lists of advantages and disadvantages. I read them  carefully, but still I cannot change my mind to understand why the mass prefer avoiding prefix to differentiate static and instance fields. Despite all the progress made in IDE and text editor, consuming an instance field is not obviously differentiated with consuming a static fields. But in terms of behavior, a static field is something completely different than an instance field, so I need to differentiate them at a glance.

When I code review code that doesn’t follow any form of field prefixing, I found myself constantly checking, and this takes time and friction. Sure one can prefix every usages of an encapsulated instance field with the this reference, but I don’t understand: why following a guideline that applies to the N usages of a field, instead of following a guideline that applies to a single declaration?

Things can get worst if you have non encapsulated fields with name non prefixed. Callers then doesn’t know if they are using a field or a property accessor. And since, having non-encapsulated field is a very bad practice (I won’t debate here on this) having fields prefixed also make calls like obj.m_State = 3 ugly enough to make you feel that something is wrong in the API, and make you want to fix it by encapsulating the field.

In many code bases, I can see that local variables naming follow the same sort of Camel-Case naming than instance and static fields. For me as a programmer, this is pretty much a nightmare to distinguish between the 3 scopes of each state when reading a complex enough method body!!!

As a last note, everybody follows the naming guideline on interface, to prefix them with an upper I. This is actually Hungarian notation that makes it easy to distinguish classes and interfaces. But really, I don’t see any conceptual difference with field prefixing.

I understand it is a matter of habits for everyone, me included. Habits means that we rely on passion instead of relying on reasoning. But when Hungarian notation is accepted for interface naming, I wonder, why all this hate on Hungarian notation for field naming that similarly offer so significant advantages? Am I missing something?

At least, I am glad to make Ayende laugh with default NDepend rules :)

This entry was posted in API usage, C#, Naming Conventions, NDepend. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://devtalk.net Dmitri

    Thanks :)

  • PatrickSmacchia

    Btw, you do an awesome job on R# congrat to all the team :)

  • PatrickSmacchia

    This is not my opinion, as I explain in the post.

    >When I code review code that doesn’t follow any form of field prefixing, I found myself constantly checking, and this takes time and friction.

  • http://devtalk.net Dmitri

    There’s no real reason to do this.

  • PatrickSmacchia

    >the name of a field won’t be in the method’s parameter list.

    Ok, but what about distinguishing instance vs. static fields at a glance?

  • PatrickSmacchia

    Appove

  • http://devtalk.net Dmitri

    In C#, there’s absolutely no reason whatsoever to use the _ previx for members, let alone s_ and m_, which are IMHO remnants of the MFC era. Constructor assignments can do this.foo = foo, and from then on you don’t have to disambiguate, as in 99.9% of cases, the name of a field won’t be in the method’s parameter list.

  • ekdikeo

    It depends on the situation. When I was programming in UnrealScript, I found it absolutely positively distracting to attempt to use hungarian anything. Of course, there were also a lot of people using strings to store trace hit data, just because it made for funny variable names. Which is a really dumb reason to use strings for that.

    In C++, I’d go insane if I had to figure out if a variable was static or method, constantly. I’ve never seen anyone extend C++ variable names with anything more than static or method flagging, though. Not sure why, because in C it was pretty much constant to use the full Hungarian.

    If you have a class with more than 1 or 2 static members, and 1 or 2 method members, you’d probably go nuts, too, if you didn’t have a way to flag those quickly.

    Also, a lot of people out there are quite professional programmers, without using any of those tools you mention — those tools only exist for Windows.

  • Ruben Bartelink

    If you read the comments in the annotated FDG re the I* prefix, you’ll find that it’s more of a historical accident than something to cite as a justification for anything.

    An alternative to consider for static access prefixes is (a la using a [redundant] this. on field accesses) to use a redundant TypeName. prefix.

    (I personally would be happy to use a this. prefixing for fields if it was enforced by the language but until I can be confident the absence of a this. has significance I don’t like them)

  • http://www.joshka.net/ Joshua McKinney

    I’m going to go out on a limb and say that if your class is so big that you need prefixes to work out which identifiers are variables, instance fields, and static fields, your problem isn’t the naming of identifiers. It is instead collecting them into a coherent class following the SRP. Fix the latter problem and first becomes irrelevant to the point of where it really doesn’t matter what convention you use.

  • Stefan Schor

    We are using prefixes for development

    - m_ for instance members
    - s_ for static members

    - c_ for constants

    The Reason is simple: If you decide to use m_ for instances then it make sense also to use variants (e.g. static) of it.

    Why this type of prefixes (my opinion)?

    - There are sometimes scopes (e.g. methods like SetFooAndBlub()) where you have…
    a. The parameter of the method (e.g. SetFooAndBlub(int foo, string blub) or local variables
    b. The public Property (e.g. Foo, Blub)
    c. The backing field (e.g. m_Foo, m_Blub)
    => Using prefixes for the fields leads to less naming conflicts and the code becomes more obvious

    - I like it to see at first glance that a field is static or not.

    - I use this type of prefixes in general just on private/protected fields.
    If fields are public I prefer CamelCase Naming (e.g. for internal data structures, …)

    Best regards,
    stefan

  • Chris Wegener

    I also use the underscore but postfix the field names. It is not intrusive and highlights a specific decision not to use a property or to allow the same name for the property and the field. I admit I started before all of the tools already mentioned helped clean up code.
    Sometimes for a simple class properties are not esential but I want the code to make that choice clear.

  • PatrickSmacchia

    >It’s a religious war, which you yourself already admitted, yet you want to continue to use rationalizations to force your opinion on others. ;)

    Actually I’d be glad to read here a point that could make me change my mind. In the past there are plenty of points on which I’ve changed my mind afterthought. But on this point, I bet I won’t :)

  • willy_duit

    The tooling you mention, for the most part, follow the FDG by default and would ask you to remove the warts. Yes, I know you can change the behavior, and yes, such tooling would “enforce” usage, but that misses the point. The language/compiler don’t care, so anything else is strictly a preference of the developer. It’s a religious war, which you yourself already admitted, yet you want to continue to use rationalizations to force your opinion on others. ;)
    I never said that proper naming would tell you everything about the type, I said it would tell *me* more than enough. In my 20+ years of programming I’ve never struggled with reading and understanding code written without Hungarian warts, unless said code was poorly written (such as bad naming) to begin with.
    I’m not trying to convince you I’m right. I’m trying to point out how I hold a totally different point of view, i.e. preference, to you. My point of view is just as valid as yours. In the end, though, the only POV that matters is the conventions used by the language and libraries provided by the compiler you use. You should conform to that, for the sake of everyone else, regardless of your opinions. Really dislike it? Choose another language to use.
    I hate Java conventions, but when I work with Java I follow them. I dislike “I” and “T”, but I use them in .NET. “When in Rome…”

  • PatrickSmacchia

    R# helps enforce a guideline, it doesn’t help differentiate between variables, instance fields and static fields at a glance if no naming guideline is applied.

  • PatrickSmacchia

    >The language and compiler don’t care, so nothing enforces the usage.

    Unless you are using tooling.
    And nowadays working without at least a tool like R#, CodeRush, FxCop, NDepend… is just not professional.

    >If you’re doing even a half way decent job with naming and code structure then I generally know more than enough about a variable without having to fall back to using warts to tell me every little detail about it.

    I don’t agree, proper naming doesn’t necessarily bring all information needed to differentiate between variables, instance fields and static fields. And when it does, this clearly is subject to developer understanding.

    > I do follow some FDG conventions that give me more information, mostly because there’s compelling reasons other than knowing the minute details of the type (not to mention the conformity to existing code)

    But programming is all about knowing the minute details of the class you are currently developping/refactoring/reviewing. Any facility that helps loading and mastering all the class details in my mind is welcome.

  • mxmissile

    who cares? this is why god invented resharper

  • willy_duit

    I find it interesting that you spent so many words on this blog post trying to convince others to use Hungarian notation, while you summarize why it’s pointless so nicely. “I understand it is a matter of habits for everyone, me included. Habits means that we rely on passion instead of relying on reasoning.” None of your attempts to rationalize your own “passion” are compelling to anyone who doesn’t already share your preference.
    Personally, I find Hungarian warts (I refuse to call them notation) to be far to “inside baseball” to really be helpful. The language and compiler don’t care, so nothing enforces the usage. The notation is cryptic, so you have to rote memorize it. Worse, because it’s impossible for Hungarian warts to cover every possible bit of metadata, people make up their own warts that others than have to learn and memorize. Most people agree that variable names like “a”, “b”, “c”, “n”, “ct”, etc. are meaningless and inappropriate to use except maybe in some corner case scenarios, like as a loop counter. It’s far better to use meaningful names like “count”, “amount”, “serverAddress”, etc. So I find it really weird that people then turn around and think that “m_”, “s_” and other such warts are meaningful.
    I’d rather have no Hungarian warts. Unfortunately, the FDG says we should use to warts, “I” for interfaces and “T” for generic type parameters. Failing to follow these guidelines just because you want to be a purist about Hungarian usage just makes your code stick out like a sore thumb, which is at best distracting when reading code. So, I follow those guidelines somewhat reluctantly.
    The arguments for Hungarian warts have never really resonated with me, even when I used it in C/C++ in the 90s. If you’re doing even a half way decent job with naming and code structure then I generally know more than enough about a variable without having to fall back to using warts to tell me every little detail about it. I do follow some FDG conventions that give me more information, mostly because there’s compelling reasons other than knowing the minute details of the type (not to mention the conformity to existing code). I use the “this.” prefix, not only because it tell me it’s an instance but also because it helps with IntelliSense, for instance.

  • PatrickSmacchia

    ‘m_’ and ‘s_’ might look ugly, this is subjective (I don’t find it ugly), but it seems to me to be more understandable than any other convention serving that matter.

  • RenniePet
  • Peter Morlion

    I actually just use ‘_’ for instance fields (which are always private) and uppercase for static fields. Though the underscore might be considered as Hungarian also. But I find the ‘m_’ and ‘s_’ (which I used to use) give for an ugly look to the code (the fact that I want code to ‘look’ nice might be a strange twist in the head).