C# – Why are prefixes on fields discouraged

ccoding-standardsnaming-standards

Back in the old days, we did Hungarian notation. That's now considered passé, and for the most part I don't use it anymore, but I still find use for the m_ prefix to indicate member fields.

For me, if I'm reading through someone else's code, and I see this:

count = 3;

I assume that count is a variable local to that function and I'm doing something that will be used elsewhere in the function; if I see this:

m_count = 3;

I immediately realize that I'm updating the state of the object.

The Microsoft style guidelines say that's the wrong way to do things. I'm supposed to name my non-public fields exactly like temporary variables defined within the function. No m_, not even a simple underscore.

Yes, we can define our own coding style, but then I have to wrestle with various static code analysis tools, to convince them that our way of doing things is OK.

I'm happy to change to the Microsoft style, but I'd kind of like to know why things are the way they are.

Why is it now considered bad to be able to tell whether a variable is function local or a member?

P.S. This is very similar to What is the regarded current best practises regarding the “this” keyword in front of field and methods in c#?, but I'm asking about m_ not this.

P.P.S. Also see Why did Microsoft make parameters, local variables and private fields have the same name naming convention?

Best Answer

When they were working on the API for Windows, Microsoft recommended the use of Hungarian Notation, using 'm_', as well as 'i', 'sz', etc. At the time, this was useful because the IDE wasn't robust enough to show this information to you.

C#, on the other hand, has a very robust IDE from the outset.

So they made the recommendation in Microsoft's Naming Guidelines for C# for public static or protected fields:

✓ DO use PascalCasing in field names.
✓ DO name fields using a noun, noun phrase, or adjective.
X DO NOT use a prefix for field names.

Now that you can hover over it with your mouse, or press CTRL+K+W, and get all the information about the member, Microsoft came to the determination that prefixes are bad form; they are a manual solution to an already solved problem.

Private fields are specifically excluded from the guidelines, but Microsoft seems to have come to the conclusion that this is the case even for private fields going forward internally, which you can see if you point Resharper at .NET 4.5 or .NET Core.

Use your tools, don't do it manually.