« Seven more ways to improve legacy Java | Main | What's in an envelope? »

C# code conventions I'll be breaking for the time being

Here are two conventions I won't be following, with reasons:

Pascal case method names

Maybe it's just years of Java and Python showing, but I find ObjectName.MethodName() hard to read compared to ObjectName.methodName() . I tried to to adapt to this, I really did, and it's not due to taste matters. My brain keeps telling me I'm dealing with inner classes. I have to saccade out to the () to see what I'm dealing with - this is not irrelevant after a some hours of programming.

Prefixing interfaces with 'I'

Son of Hungarian notation alert. I just don't care enough that something is an interface and not a class to plonk 'I' in front of it. Why aren't we plonking 'C' in front of classes? Even so, I find having this distinction useless in working code - it's going to be irrelevant to me as a caller of your code what type model your implementation went with. One's an object signature, the other's an object generator+signature. But what do I care? If I'm using 'new' I know it's an object and if I'm using a function or factory it's irrelevant. All it does it make it look like Java circa 1999 with that 'IF' postfix convention. Doh.

May 3, 2004 07:00 PM


Mike Kozlowski
(May 3, 2004 09:04 PM #)

You might as well just crack and follow the conventions now, because if you're writing a normal app, you're going to have to use .NET Framework methods, and those use the PascalCase and IInterface conventions, so at best, doing things your way will result in mixed-convention code.

The habit I've been unable to break is declaring strings with a class name ("String") rather than a native type name ("string")...

Robert Sayre
(May 3, 2004 11:25 PM #)

Man, I hate all of those things, too. But I think I would rather code in C# than Java, if I was allowed to choose my punishment.

Bill de hra
(May 4, 2004 12:24 AM #)

"...so at best, doing things your way will result in mixed-convention code."

That's /exactly/ what's bothering me with my stance. I don't see Pascal case ever going away (if only because it's standard in the VB world). Otoh I'll be surprised if 'I' isn't dropped as a bad idea in time.

Jon Hanna
(May 4, 2004 10:07 AM #)

The I prefix is a legacy from the COM world, where having the distinction made clear was ideed beneficial because of the way the interface of a COM component would be defined entirely in terms of such interfaces (just how beneficial is a different matter, it was irritating when the most natural name for your co-class happened to begin with the letter I).

It wasn't unheard of for people to begin class names with C (in particular MFC classes begin with C, originally to distinguish a Windows system type from the MFC class that wrapped it, but the convention took hold beyond that) or even cls (VB coders do this a lot. One of my first jobs if I took over VB code from another developer would be to find-and-replace any name beginning with cls to something more sensible).

(May 4, 2004 07:27 PM #)

The reason for the I prefix is precisely what you said: how can you tell if you can call "new" on a type if it doesn't follow this naming convention?

Bill de hra
(May 4, 2004 08:51 PM #)

" how can you tell if you can call "new" on a type if it doesn't follow this naming convention?"

I guess you could try and see what happens. Seriously, this is a non-problem.

Robert Johnson
(May 4, 2004 09:32 PM #)

I just wish people would adopt Robert Martin's style of member variable names:

public class SomeClass
private int itsNumber;
private static int theirNumber;

The "its" and "their" prefixes make code much easier to read and conceptualize as opposed to "m_" and "this.". This convention also follows Booch's recommendation that code should read like well-written English.

(May 5, 2004 08:53 AM #)

I'm with Bill on this, but I expect I'll cave when I have to use the stuff (which is on the agenda).

I've never liked m_, that seems a bit East European too. I generally use this.thing, but even that didn't prepare me for Python's self, self, self...

I like the idea of theirNumber for statics, but will I remember..?

Jon Hanna
(May 5, 2004 10:28 AM #)

The only convention I'm reasonably consistent with is m_ the reason being that the more something should be avoided the more ugly it should be. Private member access should be avoided more than public function access (especially when any supposed efficiency gains in accessing the private member directly is optimised away) so it should be more ugly.

I love the way the C++ casts (not the catch-all cast that is part of it's legacy from C) are really really ugly, and awkward to type - a little rap across the knuckles every time you cast something :)

Robert Watkins
(May 6, 2004 12:53 PM #)

Cedric: "how can you tell if you can call "new" on a type if it doesn't follow this naming convention?"

Me: Compilation errors, anyone? More seriously, who cares? The type is the important part, not the fact that you can create an instance. Are you sticking 'I' in front of your Abstract classes?

Alternatively: why not "decorate" your instantiable classes instead? At least that way, if the decoration gets annoying, you could hide it behind the (non-decorated) interface instead.

Damian Cugley
(May 6, 2004 04:40 PM #)

In C# I exploit the fact that method and property names start with capital letters by having member variables always start with lower case.

public void AddHat(Hat newHat) {
if (hat == null) {
hat = newHat;
} else {
throw new HeadFullException();

You cannot do this in VB .NET because it ignores case. When forced to program in VB I use the SmallTalk style of myFoo, ourFoo, with aFoo as the default name of parameters to member functions:

Public Sub AddHat(aHat As Hat)
If myHat Is Nothing Then
myHat = aHat
Raise New HeadFullException()
End If
End Sub

In VB the equivalent of 'self' or 'this' is 'Me', so 'my-' seems particularly apt.

Asbjrn Ulsberg
(May 10, 2004 12:43 AM #)

I liked the Java and JavaScript convention with camelCasing and _ prefixing of private variables and stuff, until I had programmed C# for a couple of months.

Then I realized that prefixing just was another variant of the Hungarian crap, and that keeping every public or protected property, method, etc., pascal cased made it a lot easier to have pretty local code as well. No need for prefixing. Lower case variables are suddenly private by default.

I'm with you on the 'I' prefix, though. The only problem I see, is that you can get into a lot of problems with having an implementation of an interface called the same as the interface. No problem if they're in different namespaces, but that might not always be the case. It's no big problem either way, though. You use the interface directly so seldom that it's no fuzz, imho.

What bugs me a hell of a lot more, is that @" strings aren't finished with "@, so you could write " inside of them, without having to double them up (""). Python solves this with four initial and ending quotes, and PHP with a terrible '[keyword]

Tom Hawtin
(May 10, 2004 08:44 PM #)

You've got to fit in with conventions, otherwise you'll end up with a less worthwhile mess.

However, I do agree the I interface prefix is nonsense. The often given reason that it indicates that you can't "call new on it" is BS. There are classes you can't "call new" on. Should abstract classes be prefixed with A. Some convention for classes with private, package private or protected constructors? What if none of the constructors are no-args? See also my weblog of the differences to client code of interfaces and abstract classes.

I also prefer camel-case to initial caps. But I'm not about to start doing that in Java.

m_ and friends are evil. Not written much code with it, but I have had it cause two errors. Exactly the same number of errors as in all of my conventional code, which adds up to over ten times as much. It also makes the code look nasty. I've had enough of looking at Perl for ${deity}'s sake. Keep code as clean as possible. If you must prefix member variables, prefix them with this.

Making casts ugly. In 1.5 you could use MyType.class.cast(myBaseRef); giving only slightly impaired performance, I hope. Maybe.

Trackback Pings

TrackBack URL for this entry: