When I attended
Guerrilla .NET a few years ago at DevelopMentor,
Mike Woodring and
Keith Brown were showing examples to the class using the underscore
prefix for private class field names. It was a cool trick that the Microsoft
developers were using internally at the time. I've adopted that practice, and if you look at
the framework code using
Reflector, you
can see the underscore prefix (and "m_" in some cases) for private variables.
For the record, I have been watching the
Designing .NET Class Libraries videos as they are released on the Microsoft
.NET Framework Developer Center. I'm not 100% confident, but I think
Brad Abrams mentioned
that they do not use underscores at all anymore, but he seemed reluctant
to tell developers how to name local or private variables. Either way, I'm
trying to do the right thing. :-)
Anyway, here's a couple of interesting notes. First, using the underscore
prefix is not CLS compliant, so you definitely shouldn't use them for public or
protected fields. In fact, you shouldn't even have public or protected fields if
you can avoid it. Here's a quote a
comment posted by Brad on Kevin Dente's blog:
"Well, not excatly what you are looking for, but one fix here is
to not have any public or protected fields. There is just no reason to
expose those. You can always use a property to abstract them. That will
save your butt some day when you change some implementation details
without breaking client code."
If you decide to ignore this rule and create a protected field for example,
and then expose a public property for it later, you can run into problems if you
camel-case the protected field name and Pascal-case the public field name using
the same name. For example, Visual Basic is not case-sensitive so it can't tell
the difference:
public
class Foo
{
protected
int bar;
public
int Bar
{
get{return
this.bar;}
set{this.bar
= value;}
}
}
Public
Class FooDerived :
Inherits Foo
Public
Sub SomeMethod()
' problem, this accesses
property set
' because VB is not case
sensitive
Me.Bar = 1
End
Sub
End
Class
Of course, you will get a compiler warning about this if you build the
project containing the Foo class with the
CLSCompliant attribute on the assembly. This means that using the same name
for a protected field and property name (despite the case difference) is not CLS
compliant. Using the CLSCompliantAttribute is not the default in
a C# project, nor do I talk to many C# developers that think to include that
attribute. Seemed worthy of a note.