36

Before using C#, C++ was my primary programming language. And the Hungarian notation is deep in my heart.

I did some small projects in C# without reading a C# book or other guidelines on the language. In those small c# projects I used something like

private string m_strExePath;

Until I read something from SO that said:

Do not use Hungarian notation.

So why? Am I the only person that has m_strExePath or m_iNumber in my C# code?

Gavin Miller
  • 43,168
  • 21
  • 122
  • 188
Jason
  • 479
  • 1
  • 4
  • 6

19 Answers19

53

Joel Spolsky has a really good article on this topic. The quick summary is that there's two types of Hungarian notation that are used in practice.

The first is "Systems Hungarian" where you specify the variable type using a prefix. Things like "str" for string. This is nearly useless information, especially since modern IDEs will tell you the type anyway.

The second is "Apps Hungarian" where you specify the purpose of the variable with a prefix. The most common example of this is using "m_" to indicate member variables. This can be extremely useful when done correctly.

My recommendation would be to avoid "Systems Hungarian" like the plague but definitely use "Apps Hungarian" where it makes sense to. I suggest reading Joel's article. It's a bit long winded but explains it much better than I could.

The most interesting part of this article is that the original inventor of Hungarian notation, Charles Simonyi, created "Apps Hungarian" but his paper was horribly misinterpreted and the abomination of "Systems Hungarian" was created as a result.

Community
  • 1
  • 1
17 of 26
  • 27,121
  • 13
  • 66
  • 85
  • We've had this discussion before, and I can totally see the point of "Apps Hungarian" but I would like to point out that in C++ this also wasn't necessary, if you use the technique described in Scott Meyers' book "Effective C++", Item 18, page 78. – Dave Van den Eynde Apr 20 '09 at 14:05
  • 3
    I've got the 2nd Edition and Item 18 is "Strive for class interfaces that are complete and minimal" which isn't related to this. – 17 of 26 Apr 20 '09 at 14:11
  • 9
    I don't see the point in Apps Hungarian when the IDE can tell you if something is a member variable. – Camilo Martin Nov 02 '10 at 06:44
  • 1
    @CamiloMartin Personally I use it sometimes so my constructors look like (with a parameter of `something`) `this._something = something` instead of `this.something = something`; without some way to differentiate fields from parameters, I once typed `something = something` causing the field to be initialized to zero which was hard to catch later on. Note that the .NET reference source in some places still uses `m_MemberVariable` for private variables, and MSDN no longer specifies a naming convention for private fields. – jrh Jun 22 '18 at 18:22
  • 1
    Also for cases where auto-properties don't work, returning `MyProperty` instead of `myProperty` will cause a `StackOverflowException`; intellisense will happily auto-complete to `MyProperty` if you start typing it and hit tab at the wrong time, it is not so easy to do if you prefix your fields. [See also: Jeff Atwood's article](https://blog.codinghorror.com/properties-vs-public-variables/). – jrh Jun 22 '18 at 18:24
34

When doing user interface design, I have found it very useful to maintain Hungarian notation. Items like text boxes, labels and drop down lists are much easier to quickly understand and often you get repeating control names:

lblTitle = Label
txtTitle = TextBox
ddlTitle = DropDownList

To me that's easier to read and parse. Otherwise, Hungarian notation doesn't fit in because of the advances in IDE's, specifically Visual Studio.

Also, Joel on Software has an excellent article related to Hungarian notation titled: Making Wrong Code Look Wrong which makes some good arguments for Hungarian notation.

Gavin Miller
  • 43,168
  • 21
  • 122
  • 188
  • 15
    I disagree. I think it is even worse in this case, especially when you get into controls with longer names or the 3 letter abbreviation clashes with the 3 letter abbreviation of another control. We instead use TitleLabel or TitleTextBox or TitleDropDown etc. – John Apr 20 '09 at 13:46
  • 3
    @John: I totally agree. There's no character limit for us and we should make the variables nice and readable. – Jeff Yates Apr 20 '09 at 13:56
  • 4
    @Jeff & John - Just because we have no character limit doesn't mean it should be used. Smaller succinct variables > Longer expressive variables – Gavin Miller Apr 20 '09 at 14:07
  • 4
    I still disagree. There is little justifiable reason for terseness over descriptiveness. A variable name should be as long as it needs to be. There is a happy middle ground between m_lblName and theLabelThatHoldsSomeonesName. – Jeff Yates Apr 20 '09 at 14:12
  • 2
    I do this too, and I think it makes perfect sense. More often than not you'll be working on your controls from the code-behind, and the objects aren't declared there, but rather in some mark-up. I like to know the type of the stuff I'm working with from codebehind, without having to look in the markup :) – cwap Apr 20 '09 at 14:59
  • @Gavin - I actually don't disagree and do another extension. I will do `ui_lblTtile` and `ui_txtTitle` Reasoning? 2 fold: 1. I'm not scared to use Hungarian notation on UI controls because I don't ever recall casting a dropdown to a textbox at runtime and violating its naming. 2. the `ui_` notation (or `ux_` if you prefer) catches on nicely in code via intellisense. All UI controls are in order in a group and very convenient. Really as everyone says, just be consistent on throughout the team! – atconway Nov 28 '12 at 15:36
  • 1
    Agree. Consider `nudTotalItems` versus `totalItemsNumericUpDown` : both names convey the same information but I find the first one more readable. Still, it is just a matter of personal taste . – Jack Griffin Oct 18 '14 at 13:46
30

You're not the only person, but I'd say it's relatively uncommon. Personally I'm not a fan of Hungarian notation, at least not in the simple sense that just restates the type information which is already present in the declaration. (Fans of "true" Hungarian notation will explain the difference - it's never bothered me that much, but I can see their point. If you use a common prefix for, say, units of length vs units of weight, you won't accidentally assign a length variable with a weight value, even though both may be integers.)

However, for private members you can pretty much do what you want - agree with your team what the naming convention should be. The important point is that if you want your API to fit in with the rest of .NET, don't use Hungarian notation in your public members (including parameters).

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • @Jon : they say using hugarian is not a good practise but any real issue? does it cause any harm specifically (effeciency/compiler issue anything )? persoanlly i dont use it in my class but for the visual items like textBox,labels etc i use txt and lbl 's respectively. Please comment. – Prerak K Apr 20 '09 at 14:14
  • 2
    No, variable names don't change efficiency or compile-times etc. They affect readability more than anything else. (Oh, and varying public members just by case will limit the ability to use the type from case-insensitive languages such as VB.) – Jon Skeet Apr 20 '09 at 14:28
21

No, you're not the only one who does it. It's just generally accepted that Hungarian notation isn't the best way to name things in C# (the IDE handles a lot o the issues that Hungarian notation tried to address).

Justin Niessner
  • 242,243
  • 40
  • 408
  • 536
  • 1
    How does the IDE handles any issue that the true Hungarian notation addresses? I'm not talking about the .Net types here, see Joel's article in the top answer. – Eldritch Conundrum May 09 '12 at 08:58
12

Hungarian notation is a terrible mistake, in any language. You shouldn't use it in C++ either. Name your variables so you know what they're for. Don't name them to duplicate type information that the IDE can give you anyway, and which may change (and is usually irrelevant anyway. If you know that something is a counter, then it doesn't matter whether it's an int16, 32 or 64. You know that it acts as a counter, and as such, any operation that's valid on a counter should be valid. Same argument for X/Y coordinates. They're coordinates. It doesn't matter if they're floats or doubles. It may be relevant to know whether a value is in units of weight, distance or speed. It doesn't matter that it's a float.).

In fact, Hungarian notation only came around as a misunderstanding. The inventor had intended for it to be used to describe the "conceptual" type of a variable (is it a coordinate, an index, a counter, a window?)

And the people who read his description assumed that by "type" he meant the actual programming language type (int, float, zero-terminated string, char pointer)

That was never the intention, and it is a horrible idea. It duplicates information that the IDE can better provide, and which isn't all that relevant in the first place, as it encourages you to program at the lowest possible level of abstraction.

So why? Am I the only person that has m_strExePath or m_iNumber in my C# code?

No. Unfortunately not. Tell me, what would exePath be if it wasn't a string? Why do I, as a reader of your code, need to know that it is a string? Isn't it enough to know that it is the path to the executable? m_iNumber is just badly named. which number is this? WHat is it for? You have just told me twice that it is a number, but I still don't know what the meaning of the number is.

jalf
  • 243,077
  • 51
  • 345
  • 550
  • 3
    The IDE can provide the type, but only if I waste a second of my time hovering over the variable name :-) I'd rather be able to see it at a glance... And to provide a counterpoint to your example: exePath might well be a System.IO.FileInfo object, a wrapper for a file path that provides easy access to common file system operations. I honestly don't see the harm in prefixing variable names. I find that it makes code inspection and debugging easier. – Jordan Rieger Nov 11 '11 at 22:21
  • 4
    What do you need the type for though? When I program, I want to know what a variable *represents*, not which type it is. If your `exePath` is of type `FileInfo`, it's badly named, and then **that** is your problem. The variable's name says that it is a path, not an actual file. So when I use it, I expect it to behave like a path name, and not like a file. – jalf Nov 12 '11 at 11:18
10

You're certainly not the only person, but I do hope you're part of a declining trend :)

The problem with Hungarian notation is that it's trying to implement a type system via naming conventions. This is extremely problematic because it's a type system with only human verification. Every human on the project has to agree to the same set of standards, do rigorous code reviews and ensure that all new types are assigned the appropriate and correct prefix. In short, it's impossible to guarantee consistency with a large enough code base. At the point there is no consistency why are you doing it?

Furthermore tools don't support Hungarian notation. That might seem like a stupid comment on the surface but consider refactoring for instance. Each refactoring in a Hungarian naming convention system must be accompanied with a mass rename to ensure that prefixes are maintained. Mass renames are susceptible to all sorts of subtle bugs.

Instead of using names to implement a type system, just rely on the type system. It has automatic verification and tool support. Newer IDE's make it much easier to discover a variable's type (intellisense, hover tips, etc ...) and really remove the original desire for Hungarian Notation.

JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
6

One downside of Hungarian notation is that developers frequently change the type of variables during early coding, which requires the name of the variable to also change.

Patrick Peters
  • 9,456
  • 7
  • 57
  • 106
  • It depends. If you use "i" as general integer value and dont bothwer with the size in bytes `int iOne; int8_t iTwo; int_64_t iThree;`. Then the problem with changing type is not a big deal, but if you do often change type, you might have other more severe problems coding. Using some types for standard values and the full object name as prefix when using object values will make the code much easer to read when it is complex. And you shoud select the styleguide based on harder parts in code, not the easy parts. – Per Ghosh Apr 02 '22 at 00:50
5

unless you are using a text editor rather than the VS IDE there is little value to hungarian notation and it impeeds rather than improves readability

kloucks
  • 1,549
  • 9
  • 11
5

The real value in Hungarian notation dates back to C programming and the weakly typed nature of pointers. Basically, back in the day the easiest way to keep track of the type was to use Hungarian.

In languages like C# the type system tells you all you need to know, and the IDE presents this to you in a very user friendly way so there is simply no need to use Hungarian.

As for good reason to not use it, well there are quite a few. FIrstly, in C# and for that matter C++ and many other langause you often create your own types, so what would be the Hungarian for a "MyAccountObject" type? Even if you can decide on sensible Hungarian notations it still makes the actual variable name slightly harder to read because you have to skip past the "LPZCSTR" (or whatever) at the start. More important is the maintainance cost though, what if you start of with a List and change to another type of collection (something I seem to do a lot at the moment)? You then need to rename all your variables that use that type, all for no real benefit. If you had just used a decent name to begin with you wouldn't have to worry about this.

In your example, what if you created or used some more meaningful type for holding a path (e.g. Path), you then need to change your m_strExePath to m_pathExePath, which is a pain and in this case not actually very helpful.

Steve
  • 8,469
  • 1
  • 26
  • 37
3

The only two areas where I currently see any form of Hungarian notation are:

  • Class member variables, with a leading underscore (e.g. _someVar)
  • WinForms and WebForms control names (btn for Button, lbl for Label etc)

The leading underscore on member variables seems like it is here to stay with us for a while longer, but I expect to see the popularity of Hungarian on control names to wane.

Richard Ev
  • 52,939
  • 59
  • 191
  • 278
3

Most hungarian notation describes what the variable is (a pointer, or a pointer to a pointer, or the contents of a pointer etc. etc.), and what the thing that it points to is (string etc).

I've found very little use for pointers in C#, especially when there's no unmanaged/pinvoke calls. Also, there's no option to use void* so there's no need for hungarian to describe it.

The only left-over from Hungarian that I (and most others in C# land) use, is to preceed private fields with _, as in _customers;

Steve Dunn
  • 21,044
  • 11
  • 62
  • 87
  • 2
    That way you instantly know if a variable is a local or instance variable and it is useful in combination with intellisense cause all private fields are displayed on top together and you can find any instance field just by typing _ – Mauro Sampietro Sep 05 '16 at 13:51
2

Hungarian notation found its first major use with the BCPL programming language. BCPL is short for Before C Programming Language and is an ancient (designed in 1966), typeless language where everything is a word. In that situation, Hungarian notation can help with naked-eye type-checking.

Many years have passed since then...

Here's what the latest Linux kernel documentation says (bold mine):

Encoding the type of a function into the name (so-called Hungarian notation) is brain damaged - the compiler knows the types anyway and can check those, and it only confuses the programmer.

Please also note that there are two types of Hungarian notation:

  • Systems Hungarian notation: The prefix encodes physical data type.

  • Apps Hungarian notation: The prefix encodes logical data type.

Systems Hungarian notation is no longer recommended due to type-checking redundancy which is in turn due to advancement in compiler capabilities. However, you may still use Apps Hungarian notation if the compiler doesn't check logical data types for you. As a rule of thumb, Hungarian notation is good if and only if it describes semantics that are not available otherwise.

Cyker
  • 9,946
  • 8
  • 65
  • 93
1

If Hungarian notation is deep in your and your team's and your company's heart, by all means use it. It is no longer considered a best practice as far as I can read from blogs and books.

Otávio Décio
  • 73,752
  • 17
  • 161
  • 228
1

If you hold the pointer over the variable in VS it will tell you what type of variable it is, so there is no reason to go with these cryptic variable names, esp as people that are coming from other languages may need to maintain the code and it will be an obstacle to easy reading.

James Black
  • 41,583
  • 10
  • 86
  • 166
0

It depends.

Is it significant enough to add the description of the data type in variable/object name in your method/class?

System Hungarian Notation > Apps Hungarian Notation

If you are designing in procedural language (e.g. C) that has many of global variables or/and lower-API that deals with precise data types and sizes (e.g. C's<stdint.h>where 40+ different data type notations are used to describe int), System Hungarian Notation is more helpful.

Note, however, many modern programmers consider adding type information in variable name is abundant as many of modern IDEs have very convenient tools (e.g. Outline of Eclipse, Symbol Navigator of Xcode, Visual AssistX of Visual Studio, etc.). System Hungarian Notation was widely used in the earlier ages in programming (e.g. FORTRAN, C99) when type information was not readily available as a tool of the IDEs.

System Hungarian Notation < Apps Hungarian Notation

If you are working in higher-level class or method (e.g. user-defined driver class/method for your C# application), notating simple data type may not be sufficient enough to describe the variable/object. Therefore, we use Apps Hungarian Notation in this case.

For example, if the purpose of your method is to retrieve executable path and to display an error message if not found, instead of noting that it is a type of string, we note more significant information to describe the variable/object for programmers to better comprehend the purpose of the variable/obejct:

private string mPathExe;
private string msgNotFound;
melvynkim
  • 1,655
  • 3
  • 25
  • 38
0

It's about efficiency. How much time was wasted assigning the wrong value to a variable. Having accurate variable declarations are about gain in efficiency. It's about readability. It about following the existing patterns. If you want creativity, do user interface design, do system architecture. If your programming, it should be designed to make you team members job easier: not yours. A 2% gain in efficiencies is an extra week each year. That's 40 hours gained. Human productivity gains are made by compounding efficiencies.

Shawn
  • 111
  • 1
  • 2
0

I don't care, I always use a combination of Hungarian and Pascal/Camel Case.

Not for data types, but for controls. Because txtName is pretty self-explanatory. Some people will name it NameTextBox which is too long. lblAge, txtName, rdoTrue, cboCities, lstAccountInfo. Nice and quick and compact For variables, it's Pascal case for ordinary variables and properties. "firstName = txtFName.Text" (seriously if you can't look at that and realize it's a textbox, sheez). Then I'll use Camel Case for methods

public void PrintNames (string fName, string lName)
{
    lblFullName.Text=fName + " " + lName;
}

So yes, I use Hungarian case, so sue me. No one can say they don't know what those variables are and I like being able to see really quickly without having to hover over what type of variable or control it is. When I first started programming I used all caps for every variable so this is a step up. And for pity's sake, do NOT put the opening curly brace at the end of the line. Nice and symmetrical.

David Britz
  • 117
  • 1
  • 3
  • 9
0

In a language like C# where many of the limitations on variable name length do not exist that were once in languages like C and C++, and where the IDE provides excellent support for determining the type of a variable, Hungarian notation is redundant.

Code should be self-explanatory so names like m_szName can be replaced by this.name. And m_lblName can be nameLabel, etc. The important thing is to be consistent and to create code that is easy to read and maintain - this is the goal of any naming convention so you should always decide what convention you use based on this. I feel that Hungarian notation is not the most readable or the most maintainable because it can be too terse, requires a certain amount of knowledge on what the prefixes mean, and is not part of the language and therefore, hard to enforce and hard to detect when the name no longer matches the underlying type.

Instead, I like to replace Apps Hungarian (prefixes like m_) by referencing this for members, referencing the class name for static variables, and no prefix for local variables. And instead of System Hungarian (including the type of a variable in the variable name), I prefer to describe what the variable is for such as nameLabel, nameTextBox, count, and databaseReference.

Jeff Yates
  • 61,417
  • 20
  • 137
  • 189
0

At some point, you're likely to have a property

public string ExecutablePath { ... }

(not that you should try to avoid abbreviations like "Exe" too). That being the case, your question might then be moot much of the time as you can use C# 3.0's auto-properties

public string ExecutablePath { get; set; }

you now no longer have to come up with a name for the backing store variable. No name, no question/debate about naming conventions.

Obviously, auto-implemented properties aren't always appropriate.

Ðаn
  • 10,934
  • 11
  • 59
  • 95