11

I know the "I" convention has been around since COM, but I've never understood why it hasn't been reconsidered like every other naming convention before .NET has.

Consumption wise, the only thing that separates an interface from, say, an abstract class, is that they can be multiply inherited. But everything after Visual Studio 2003 has shown type signatures in tooltips, so it's as useless as all the other Hungarian notations that have been discarded.

I also thought it might be so that you can have a basic implementation of the interface with the same name, e.g. Message inheriting IMessage, but most of the .NET libraries have gone for adding the word "Base" at the end (e.g. System.Collections.ReadOnlyCollectionBase) instead -- and this makes more semantic sense.

COM interop seems to be another possible reason -- but it's not as if the wrapper classes that it generates are perfectly idiomatic .NET, so I doubt that that was an aesthetic consideration.

In one of my newer projects I've forgone the convention entirely, and it feels just fine. Is there something I'm missing?

Rei Miyasaka
  • 4,541
  • 1
  • 32
  • 36
  • 1
    You don't inherit interfaces for fulfil them, big difference. – Daniel Little Sep 15 '11 at 07:10
  • Also it seems like preference like IList and List as opposed to List and ArrayList. They probably did it because IList is not a ListBase but really is a ListInterface (not a List of type interface), if you get what I mean. – Daniel Little Sep 15 '11 at 07:14
  • @Lavinski In .NET `IList` is a general term for a sequenced, contiguous collection, random access, whereas `List` is a sequenced, contiguous, random access, *growing* collection. I think F# had it right in aliasing `List` to `ResizeArray`; that's definitely a much more descriptive name. `IList` then could have been `List`, so that doesn't seem like it would be a reason either. – Rei Miyasaka Sep 15 '11 at 07:51
  • 2
    IBaseBall and IBaseBallBase makes more sense to me than BaseBallBase and BaseBallBaseBase (silly example, I know :D) – e-MEE Sep 15 '11 at 08:09
  • @e-MEE equally silly would be IIRC, which could be an interface for the IRC chat protocol, or the acronym for "if I remember correctly". – Rei Miyasaka Sep 15 '11 at 10:17
  • You *know* it's just naming convention. And if you suspect it's not, and it serves some functional purpose - google it. What kind of answer are you after? Pointless question. – JᴀʏMᴇᴇ Mar 07 '16 at 11:13

3 Answers3

12

I think this may well be the only case when prefixes are useful.

Classes and interfaces really do have different semantics, and because both are types, are easy to mix up.
When I see a class declaration, I can instantly tell what it derives from and what it implements:

public sealed class ActivityCollection : List<Activity>, 
    IList<Activity>, ICollection<Activity>, IEnumerable<Activity>, 
    IList, ICollection, IEnumerable

It would be harder to understand if the definition looked like

public sealed class ActivityCollection : ListClass<Activity>, 
    List<Activity>, Collection<Activity>, Enumerable<Activity>, 
    List, Collection, Enumerable

And how would you call ListClass? Clearly it's not just ListBase because it's usable on its own.
So, we either have to solve a problem we just invented, or adapt a prefix that separates classes from interfaces, which is what .NET Framework designers did.

Also, personally I find it useful when I can tell from the method signature that it works with interfaces.

public void PrintLines (IEnumerable<string> source)

It's like a signal to my head: hey, I can implement this! I can feed the method whatever matches the contract.

Of course one can argue it's not that important but this is one of those little things that make the prefix worth it for me. It's especially useful when writing a lot of code with IoC containers when you constantly work with interfaces and need to easily differentiate between the two.

By the way, not only the interfaces have prefixes in .NET type system. Don't forget about the generic type parameters:

public delegate TResult Func<in T, out TResult>(
    T arg
)

This is another situation when it's extremely useful to be able to differentiate between classes and another kind of types.

Dan
  • 2,902
  • 1
  • 25
  • 30
  • 2
    You can easily understand that by knowing that "the first class is inheritance, the second class and forth are interfaces". – Saeed Neamati Sep 15 '11 at 09:17
  • 3
    This seems like a plausible reason. Java seems to have solved it a bit more nicely by simply using keywords to clarify the list: `class Dog extends Mammal implements MailmanChaser`. @Saeed you can have a class that doesn't inherit from anything, so the first type in the list is actually an interface rather than a base class. – Rei Miyasaka Sep 15 '11 at 10:14
  • +1 for the boldface part, though I can think of another place where a prefix-based convention would have been helpful: to distinguish between a field that encapsulates exclusive ownership of an `int[]` (or other object of mutable type) which it can mutate but not share, and one that encapsulates shared ownership of an `int[]` that, even though its type would allow mutation, nobody is allowed to mutate. – supercat May 08 '15 at 17:59
6

I don't think your missing anything, it's just a historical habit.

I agree with you as well and have also dropped the 'I' on a couple of small to medium projects with no detrimental effect.

Chris Lee
  • 278
  • 1
  • 6
  • 2
    What's weird though is that they threw out practically every other obsolete convention except this one. History doesn't quite explain it either. I still feel like there must have been a reason, unless it really was just internal politics -- but even then, I really can't see a reason that anyone would get upset about the I being dropped. – Rei Miyasaka Sep 15 '11 at 07:54
2

I think the only reason, according to Microsoft's Naming Guidelines about Interfaces and Classes, is that, sometimes you have conflicts between the name of the interface and the class implementing that. This goes back to the fact that interfaces are in fact the skeleton, not the meat, and the implementer class is in fact the meat (realizing the blueprint). Thus, IAnimal is only describing what an animal should have, while Animal can tell you that what it has.

However, I personally completely agree with you on the point that we could simply use Animal Base for the interface, and Animal for the class.

On the other hand, sometimes two things are conflicting so much, that a team decides to provide a convention to prevent further conflicts, in spite of already-made decisions. For example, in ASP.NET MVC, both Partial Views and Layouts (master pages), are just like a normal View, while they serve different functionality. Thus Microsoft in spite of emphasizing not to use underscore in naming, suggests to underscore Layouts and Partial Views with an underscore.

Saeed Neamati
  • 18,142
  • 23
  • 87
  • 125
  • What's wrong with `AnimalInterface` instead of `AnimalBase`? It's not a base class, it an interface. – Scott Whitlock Sep 15 '11 at 10:03
  • 3
    but what's wrong with IAnimal instead of AnimalInterface? sure we've gone all the way round to where we started - which just goes to show that some of the 'hungarian' notations were useful. Throwing them all out (except for I and T) was more pique rather than a thoughtful attempt to find a better system. – gbjbaanb Sep 15 '11 at 14:23
  • 2
    @ScottWhitlock: For me, `IAnimal` is much more readable than `AnimalInterface`. Verbose names are preferable except in cases when a simple short convention can be used for something occurring frequently enough. And interfaces are such a case. – maaartinus Jan 02 '13 at 12:19