IList, IComparable, ICarumba!

IList, IComparable, ICarumba!

Micah Martin
Micah Martin

September 07, 2006

This IConvention is an interesting one: “Let’s prefix all interfaces with a capital I.” Who thought of this? Why did they think it was a good idea?

Let’s say I want to implement the Command pattern in C#. I create the following interface…and to be true the fathers of C# I use the IConvention.

1public interface ICommand
3 void Execute();

In my application I can now write Code like this.

1public void ExecuteCommands(IList commands)
3 foreach(ICommand command in commands)
4 command.Execute();

Clearly, every object in the IList of commands is an Implementation of ICommand. And ICommand is an Interface because it starts with an I. That’s important to know because if it didn’t have the I, it might be an abstract class or even a concrete class.

And if that were the case then…well…hmmm…it doesn’t really matter. I could call the class ICommand or I could call it Command. From the point of view of the client code, maybe Command it’s an interface or maybe it’s not.

So if it’s all the same, I might as well submit to the convention and call it ICommand. Right?

Wrong! Prefixing interfaces with I is a mistake and this is why…

Assume that I really do need a Command abstraction. Should it be an interface or an abstract class?

I can’t think of any logic to put in the base class and the Dependancy Inversion Principles says interfaces are preferred. So I’ll make it an interface and follow the IConvention naming it ICommand.

After a while there are a dozen or so implementations of ICommand in the application. New implementations are popping up all the time. One day I realize that the application needs to know whether an ICommand has executed or not.

Since this affects all implementations of ICommand I can add another method to the interface:

1public interface ICommand
3 void Execute();
4 bool Executed { get; }

However, it’s not long before I realize that all the derived classes implement the Executed property with the exact same code.

They also need a boolean field. So to avoid duplicate code, I’ll use Template Method like so:

 1public abstract class ICommand
 3 private bool hasExecuted = false;
 5 public virtual Execute()
 6 {
 7 PerformExecution();
 8 hasExecuted = true;
 9 }
11 protected abstract PerformExecution();
13 public bool Executed
14 {
15 get { return hasExecuted; }
16 }

But wait! ICommand is not longer an interface. I can’t just leave that I sitting there. Clients will think it’s still an interface. So now I need to rename the class to Command without the I. Fortunately, !-ReSharper-! will help me there.

But now I’ve got the Command class in a file named ICommand.cs. Renaming the file is a bit more challenging since it has to be changed in source control as well.

So I rename the file in the subversion repository, then remove the ICommand.cs file from the Visual Studio project, and finally add the new Command.cs file to the project…whew. That silly I sure causes a good deal of hurt.

I’ve stumble over this scenario more times than I care to mention. Experience has taught me that prefixing interfaces with an I is a choice that will come back and haunt me. So I don’t do it.

Here’s my dilema. Maybe you can help me. I’ve been translating Unclebob’s Agile Software Development book into C#. In the code examples I have heeded my experience and created interfaces without the I prefix. Reviewers don’t like this.

They keep telling me that I need to add the I prefix. I’m torn. I feel in my heart of hearts that using the IConvention does more harm than good. Yet, readers of the book will be familiar with the IConvention and may be confused by examples that don’t use it. What’s the right thing to do?