34

That is the question? So how big a sin is it not to use this convention when developing a c# project? This convention is widely used in the .NET class library. However, I am not a fan to say the least, not just for asthetic reasons but I don't think it makes any contribution. For example is IPSec an interface of PSec? Is IIOPConnection An interface of IOPConnection, I usually go to the definition to find out anyway.

  • So would not using this convention cause confusion?
  • Are there any c# projects or libraries of note that drop this convention?
  • Do any c# projects that mix conventions, as unfortunately Apache Wicket does?

The Java class libraries have existed without this for many years, I don't feel I have ever struggled to read code without it. Also, should the interface not be the most primitive description? I mean IList<T> as an interface for List<T> in c#, is it not better to have List<T> and LinkedList<T> or ArrayList<T> or even CopyOnWriteArrayList<T>? The classes describe the implementation? I think I get more information here, than I do from List<T> in c#.

Rob
  • 45,296
  • 24
  • 122
  • 150
ng.
  • 7,099
  • 1
  • 38
  • 42
  • 2
    possible duplicate of http://stackoverflow.com/questions/681700/interface-naming-convention and http://stackoverflow.com/questions/541912/interface-naming-in-java and http://stackoverflow.com/questions/437649/why-prefix-c-interface-names-with-i – Lars Andren Apr 28 '10 at 09:16
  • 2
    @Lars - none of the others discuss the issue of moving code between c# and java, though; they are one **xor** the other. – Marc Gravell Apr 28 '10 at 12:10
  • 1
    IF "I" is so unacceptable in the Java world than why is "Abstract" seen as okay for Abstract classes? – Adam Gent Apr 28 '10 at 22:21
  • 2
    @Adam Gent - because usually the hierarchy goes `Interface` <- `AbstractClass` <- `ConcreteClasses`. The abstract class is just a place for common functionality. Since you should be using the class through the interface rather than the implementation, the only place the extra "Abstract" shows up is in the classes that extend it. Unlike "I"Interfaces - which "pollute" the code with that additional character everywhere they are used and implemented. – Nate Apr 29 '10 at 02:42
  • 1
    @Adam Gent - you will NEVER see a method return AbstractClass in Java its only used so that that there is a namespace for common functionality. Its not used to name any relevant type. I as a convention for interfaces is redundant, and in my opinion a bad idea. – ng. Apr 29 '10 at 08:55
  • So is suffixing with Impl okay (I agree I don't like the I prefix)? I'm just making the argument that most of this is just opinion and bias familiarity. – Adam Gent May 05 '10 at 14:17

20 Answers20

65

The difference between Java and C# is that Java allows you to easily distinguish whether you implement an interface or extend a class since it has the corresponding keywords implements and extends.

As C# only has the : to express either an implementation or extension, I recommend following the standard and put an I before an interface's name.

Ham Vocke
  • 2,942
  • 22
  • 27
  • 9
    Thats a fairly reasonable argument, never really considered the conflict there. – ng. Apr 28 '10 at 09:33
  • 12
    In Java, the 'implements' keyword is only visible in the class, which implements it, not in method which expect an ISomething. You rarely look at the first lines of an implementing class, do you? – user unknown Apr 28 '10 at 14:05
33

It's bad practice in my opionion too. The reasons why, additional to yours are:

  • The whole purpose of interfaces is to abstract away implementation details. So it shouldn't matter if you call a method with a IParam or Param.
  • Elaborated tools have their own possibilities to mark interfaces with an icon.
  • If your eye is searching in a IDE for a name, the most significant part is the beginning of a string. Maybe your classes get sorted by alphabet, and now you have a block of similar names, all starting with I... together. They look similar, while it would be of advantage to distinguish them easily. It's ergonomical wrong to use an I-prefix.
  • Even more annoying: ImplList, ImplThat, AFoo for an abstract Foo, AImplFooBar for an abstract Foo, which implements Bar? SSomething as Singleton, or SMath for a static class? Stop it! :)
user unknown
  • 35,537
  • 11
  • 75
  • 121
  • 2
    IMHO Interfaces have one aspect that can't be abstracted away compared to abstract base classes, not even in java. The require implementation instead of extension (Java => implements <=> extends). Example: If you want to create a FileSystemDriver and you only know that other methods require a "Driver". You can't know without checking the documentation wether you need to implement it or simply inherit from it. If they'd require an "IDriver" you know it's an interface and can immedatly begin implementing it. About sorting by alphabet: I prefer sorting by namespace which solves this problem. –  Apr 28 '10 at 11:01
  • The problem is that there are so many tools that only work with Interfaces that you need to know the difference. For example Java can only create Dynamic proxies of Interfaces and not Concrete or Abstract classes. Thus I find it extremely beneficial what I can and can't JMock or wrap in AOP proxied classes. – Adam Gent Apr 28 '10 at 11:59
  • 6
    @dbemerlin Thats exactly why the "I" convention is bad, you don't know its an interface, all you know is that the string "IDriver" identifies the type, the compiler does not enforce the convention. Besides which, the whole point is you should not care whether its an interface or abstract class. It should be transparent. – ng. Apr 28 '10 at 13:08
  • 3
    I have to say I agree with the argument made in this answer, if the convention was not in such widespread use in .NET I would not even ask the question, it seems a bit redundant. The whole point of a type hierarchy is that it should be transparent anyway. Why would I interact with an reference differently than I would for an abstract class or concrete class. Also, do I know for sure that a type that does not start with "I" is not an interface? Not really. – ng. Apr 28 '10 at 14:19
  • 2
    I disagree with pretty much everything in this answer. Knowing whether or something is an interface is important and having a prefix makes it easy at a glance to tell exactly what's what. – Igor Zevaka May 11 '10 at 23:02
  • Which is pretty much 1/4, because you don't adress the possibilities of modern IDEs, you don't adress ergonomics, and don't adress ambiguity problems. – user unknown Feb 08 '11 at 16:23
  • As far as ergonomics, are you suggesting that removing I from interface names somehow solves the issue of intellisense pollution? I disagree. If you are depending on alphabetic order for efficient use of intellisense, you are in serious trouble. To be proficient at using intellisense, one must already have an idea of the first few characters. Introducing the letter I is inisgnificant. On your final point, I am having a hard time finding a reputable source which makes such a proposal. The MS guidelines pretty much only address 'I'. – gravidThoughts Mar 23 '15 at 19:46
  • @gravidThoughts: As you may have noticed, I didn't refer to Intellisense in particular and in fact, I had to look this term up to find out, that it is a proprietary product. And my knowledge about ergonomics and words doesn't origin in computer literature, where I didn't met considerations about it. My experience about sorted names in packages or classes is from Eclipse and Idea. – user unknown Mar 24 '15 at 22:23
  • @userunknown Intellisense is a MS specific name for a common feature found in several non MS IDE. In Eclipse, when you type a . on an object instance, you are not provided with a list of members? Anyway, the point still holds. The addition of one character in the front of a block of member names does not make those members somehow indecipherable. Again, you are going to already have an idea of the member name anyway. If you don't, having them alphabetically in the class definition does you no good. – gravidThoughts Mar 26 '15 at 12:14
  • @gravidThoughts: Nobody spoke of indecipherable. Please avoid strawman arguments. – user unknown Mar 26 '15 at 15:12
  • @userunknown Pardon me. Any less decipherable. You are now simply evaluating characters 2-x. – gravidThoughts Mar 26 '15 at 17:00
22

With respect, in your post you are only considering your needs (I, I, I), and not the needs of the readers of your code. If you are a one-man shop, then fair enough, but if your code if ever read by others, then consider that they will be expecting interfaces to have an I prefix--that is just the way it is in .Net, and too many people are used to it to change now.

Also, it would help if you used more readable names for classes. What is PSec? How can I tell whether IPSec is an interface, when I can't even tell what PSec is? If instead PSec was renamed to e.g., PersonalSecurity, then IPersonalSecurity is much more likely to be an interface.

Polyfun
  • 9,479
  • 4
  • 31
  • 39
  • 1
    To say that well known acronyms are not in wide spread use is nonsense. The example, although a little contrived is valid. IPSec is very well known, I.P address, ever hear of it? IPSec I.P Security? – ng. Apr 28 '10 at 09:29
  • 13
    Microsoft Style Guidelines say that Classes or Methods containing the Term IPSec should be Cased IpSec, so IPSec always has to be an interface as the P is uppercase, meaning it's the start of a word/abbreviation. See HTTP (=> Http), HTML (=> Html), XML (=> Xml) and similar. Same for IOPConnection (=> IopConnection). –  Apr 28 '10 at 10:51
  • Makes sense, so camel case for acronyms resolves this ambiguity. Thanks. – ng. Apr 28 '10 at 11:10
  • 7
    @dbemerlin Actually, they say you should lowercase the later letters only if the acronym is 3 or more letters, 2 letter acronyms are to remain capitalised, hence the .net class libraries has the `System.Net.IPAddress` class: http://msdn.microsoft.com/en-us/library/system.net.ipaddress%28v=vs.110%29.aspx (Also, I'm amazed nobody spotted this sooner, that class has existed since .Net framework 1.1) – Pharap Dec 26 '14 at 05:13
11

Using I for interfaces goes against the whole point of an interface imo, that it is a connector that you can plug different concrete implementations in to dependencies.

An object that uses the database needs a DataStore, not an IDataStore, and it should be up to configuration whether that gets a DatabaseDataStore or a FileSystemDataStore or whatever plugged into it (or a MockDataStore for testing).

Mat Mannion
  • 3,315
  • 2
  • 30
  • 31
  • 2
    I don't see a difference there. Foo(IDataStore store) and Foo(DataStore store) can do the same thing, just in one case the interface name is prefixed with I. You can still pass it a DatabaseDataStore or FileSystemDataStore, they just implement IDataStore with an I prefix. –  Apr 28 '10 at 10:54
  • 3
    By that logic, you should prefix all of your variables with the first letter of their type. boolean enabled should be boolean bEnabled, int iCount etc etc. It just seems to me like a very outdated coding practice. – Mat Mannion Apr 29 '10 at 11:03
  • Booleans are polymorphic? Learn something new everyday. – gravidThoughts Mar 23 '15 at 19:50
8

Read this and move on. If you're using Java, follow the Java naming conventions.

alimbada
  • 1,392
  • 1
  • 12
  • 27
3
  1. It's not a sin per se, it's best practice. It makes things a lot more readable all in all. Also, think about it. IMyClass is the interface to MyClass. It just makes sense, and stops unnecessary confusion. Also remember the : syntax vs. implements/extends. Lastly, you can bypass all of this by simply checking the tooltips/go to in VS, but for pure readability, the standard is important in my opinion.

  2. Not that I'm aware of, but I'm sure they exist.

  3. Haven't seen any, but I'm sure they exist.

Kyle Rosendo
  • 25,001
  • 7
  • 80
  • 118
3

I think the main reason for the I-Prefix is not that those using it can see it's an interface but that those implementing/deriving from existing classes and interfaces can see more easily wether it's an interface or base class.

Another advantage is that it prevents stupid things like (If my Java memory serves me correctly):

List foo = new List(); // Why does it fail?

The third advantage is refactoring. If you move through your objects and read the code you can see where you forgot to code-by-interface. "A method accepting something with a type not prefixed with I? Fix it!".

I used it even in Java and found it quite usefull, but it always depends on the guidelines for your company/team. Follow them, no matter how stupid you may think they are, some day you will be happy they exist.

  • 3
    `// Why does it fail?`: read the compiler's error diagnostic. All confusion is now a moot point. – Thomas Eding Sep 11 '12 at 17:04
  • 1
    "The third advantage is refactoring" - works against you too. When extracting the interface from class `Foo` to interface `IFoo`, you need to change all declarations of `Foo` to `IFoo`. – Steve Kuo Jan 10 '14 at 21:23
3

Ask yourself: If my IDE could give me some hint in the text (e.g different colour, underline, italic...) that the type was an interface would I still bother?

Sounds like you are naming the types like that just so you can tell from the name something about parts of the definition other than the name.

gub
  • 5,079
  • 3
  • 28
  • 33
  • Same answer as mine but more succinct :) – Adam Gent Apr 28 '10 at 11:51
  • 1
    I would still bother - but that is because I still do printed code reviews from time to time. A personal rule of thumb is that I try not to be able to only divine a piece of information from the IDE - needs change, IDEs change, etc. What about that one developer who changes his color schemes to something monocrhomatic? ;-) – Joseph Ferris Apr 28 '10 at 16:48
  • 1
    Ok then, why not develop the idea... instead of: Stream stream why not define the type as: IStreamGenericTypeExtendsNumber stream; Try to get as much info in the type name as you can, who needs the type system anyway? – gub May 02 '10 at 16:30
2

Best practices override convention sometimes, in my opinion. While I may not personally like the convention, not using it goes against the best practice that has been in place for longer than I care to think about.

I would look at it more from the point of how other people do it, in this case. Since 99% of the common world will be prefacing with the "I", that is good enough to keep this best practice. If you have to bring in a contractor or on-board a new developer, you should be able to focus on the code and not have to explain/defend choices that you made.

It has been around long enough, and is ingrained well enough, that I don't expect it to change in my lifetime. It is just one of those "unwritten rules", better defined as an "unwritten best practice", that will probably outlive me.

Joseph Ferris
  • 12,576
  • 3
  • 46
  • 72
  • 1
    "best practice that has been in place for longer than I care to think about." - Do any other languages / environments other than .NET and COM use the "I" prefix? 1993 (for COM) and 2002 (for .NET) isn't that long ago. – Nate Apr 28 '10 at 13:04
  • From a technological standpoint, seventeen years is a *considerable* amount of time. Not to date myself, but COM was just coming on to the scene while I was still in school. ;-) Simple fact is that it was introduced with COM and it became just a widely accepted practice within that development community. Microsoft was pretty much maintaining the status quo, even if it did not fit in with their other naming guidelines. Because of the "familiarity" it became an official exception to the rule in the class design guidelines, as well. – Joseph Ferris Apr 28 '10 at 16:44
1

I would say that not following this convention would get you down to .NET hell. It's a convention that's almost as important to me as using self in instance methods in Python.

Deniz Dogan
  • 25,711
  • 35
  • 110
  • 162
1

I don't see any good reason to do this. 'Extends' vs 'implements' already tells you whether you are dealing with a class or an interface in the cases where it actually matters. In all other cases the whole idea is that you don't care.

user207421
  • 305,947
  • 44
  • 307
  • 483
1

In my opinion the biggest reason "I" is often prefixed is that the IDEs for both Java (Eclipse) and .NET (V Studio) do not make it extremely clear that the Class you are looking at is in fact an interface. The package browser in eclipse shows the same icon till you expand the class file and the font of an Interface declaration is not any different than a class.

An Example would be if I type:

ISomeInterface s = factory.create();

ISomeInterface should atleast have some sort of font modification to show that its an interface (like italics or underline).

The other big reason is in the Java world that people prefix with "I" is that it makes it easier in Eclipse to do a "Ctrl-Shift-R" and search for only interfaces.

This is important in the Java/Spring world where you need interfaces as your collaborators if you plan on using any AOP magic or some other Dynamic proxies.

Than you have the nasty choice of either prefixing your interface with "I" or suffixing your implementation class with "Impl" like ListImpl. I abhor the suffixing of classes with "Impl" to make the interface and concrete differ in name and prefix the prefix of "I".

In general I try to avoid making lots of interfaces.

In my own code I would never prefix with "I". I'm only give some reasons why people do it which is for old code consistency.

Adam Gent
  • 47,843
  • 23
  • 153
  • 203
  • Soooo many problems here... prepending "I" to an interface is far from a standard in the Java world - it goes against the naming standards. Eclipse does use a different icon for classes and interfaces (you're confusing the class/interface with the file that contains it). You can even change the syntax coloring of interfaces in the editor to anything you want (Window -> Preferences -> Java -> Editor -> Syntax Coloring -> Java -> Interfaces) "In general I try to avoid making lots of interfaces." In general you probably should... – Nate Apr 28 '10 at 13:18
  • Hey I didn't say I like doing it but my company has it as a coding standard which I first adamantly disagreed with. Yes I am aware of the newer eclipse setting and I did say "The package browser in eclipse shows the same icon till you expand the class file" which you must have not read. I was only trying to play the other side. I think you misread my post as I really am for the other side considering I think the biggest reason is because people can't setup there IDE. – Adam Gent Apr 28 '10 at 22:09
  • But why is it important to distinguish a class from an interface? From a user's perspective, I don't think it really matters. All I would care about is that the types are compatable. – Thomas Eding Sep 11 '12 at 17:06
  • ThomasEding I'm seriously contemplating deleting this post as people think I favor this crap. I only wrote reasons why people do it and I no longer work at the company that did. From the user's perspective I was only being consistent with shit code that already existed and I could see why they did it.. because they did not know how to use eclipse and eclipse didn't always support @Nate syntax color highlighting. – Adam Gent Sep 11 '12 at 17:28
  • @ThomasEding and the reason from a user's perspective also is to know what the extension points are (I mean it is the Java standard to prefix `Abstract` even if you don't have an interface in front. Like I said I don't agree with and I just generally avoid the whole problem by not making many interfaces and stick to abstract classes (I use AspectJ so I don't need the dynamic proxy crap). – Adam Gent Sep 11 '12 at 17:32
  • Yeah, I definitely agree with consistency. If I were programming in C#, I would prefix with an 'I' just so that the code doesn't look out of place, even though I don't think it is useful (even when programming in a simple text editor). – Thomas Eding Sep 11 '12 at 17:44
0

conventions exist to help all of us. If there is a chance another .net developer will be working with you then yes, follow the convention.

Thanos Papathanasiou
  • 904
  • 2
  • 12
  • 23
0

One idea is that the "I" part can be followed by a verb, stating what classes that implement the interface does; like ISaveXmlData, forming a nice human language name.

Lars Andren
  • 8,601
  • 7
  • 41
  • 56
  • I've long followed the sun convention of using nouns or noun-phrases for class naming and verbs or verb phrases for method names. See http://java.sun.com/docs/books/jls/second_edition/html/names.doc.html#29466 – crowne Apr 28 '10 at 09:36
0

The key thing is consistency - as long you stick to having I prefixed to all interfaces or none at all, it's a matter of preference.

I use the I prefix for interfaces at work since the existing code already uses it for a naming convention for each interface. I find it more intuitive to quickly determine if a class implements an interface or another class simply by looking for the I prefix in the name of the base class.

On the other hand, some of the older projects at work don't use this naming convention and this makes the code slightly less readable, but it might just be that I'm used to the prefix.

anonymous
  • 3,474
  • 25
  • 29
0

Look at the BCL. In the Base Class Libraries you have IList<>, IQueryable, IDisposable. If you don't prepend it with a 'I', how would people know it's an interface other than going to the definition?

Anyways, just my 2 cents

Pieter Germishuys
  • 4,828
  • 1
  • 26
  • 34
0

You can choose all names in your program how you like, but it's a good idea to hold naming conversion, if not you only will be read the program.

Usage of Interfaces is good not only if you design you own classes and interfaces. In some cases you makes other accents in your program it you use interfaces. For example, you can write code like

SqlDataReader dr = cmd.ExecuteReader (CommandBehavior.SequentialAccess);
if (!dr.HasRows) {
    // ...
}
while (dr.Read ()) {
    string name = dr.GetString (0);
    // ...
}

or like

IDataReader dr = cmd.ExecuteReader (CommandBehavior.SequentialAccess);
if (!dr.HasRows) {
    // ...
}
while (dr.Read ()) {
    string name = dr.GetString (0);
    // ...
}

the last one have looks like the same, but if you are using IDataReader instead of SqlDataReader you can easier to place some parts which works with dr in a method, which works not only with SqlDataReader class (but with OleDbDataReader, OracleDataReader, OdbcDataReader etc). On the other hand your program stay working exactly quick as before.

Updated (based on questions from comments):

The advantage is, like I written before, if you'll separate some parts of you code which work with IDataReader. For example, you can define delegate T ReadRowFromDataReader<T> (IDataReader dr, ...) and use it inside of while (dr.Read ()) block. So you write code which is more general as the code working with SqlDataReader directly. Inside of while (dr.Read ()) block you call rowReader (dr, ...). Your different implementations of code reading rows of data can be placed in a method with signature ReadRowFromDataReader<T> rowReader and place it as a actual parameter.

With the way you can write more independent code working with database. At the first time probably usage of generic delegate looks a little complex, but all code will be really easy to read. I want to accentuate one more time, that you really receive some advantages of using interfaces in this case only if you separate some parts of the code in another method. If you don't separate the code, the only advantage which you receive is: you receive code parts which are written more independend and you could copy and paced this parts easier in another program.

Usage of names started with 'I' makes easier to understand that now we are working with something more general as with one class.

Oleg
  • 220,925
  • 34
  • 403
  • 798
  • I don't see the point. How is `IDataReader` any better than `DataReader`? They're both more general and, strictly speaking, it shouldn't have to matter whether `DataReader` is a class or an interface. – wds Apr 28 '10 at 09:47
  • The advantage is, like I written before, if you'll separate some parts of you code which work with `IDataReader`. For example, you can define `delegate T ReadRowFromDataReader (IDataReader dr, ...)` and use it inside of `while (dr.Read ())` block. Then you write more code which is more general as the code working with `SqlDataReader` directly. – Oleg Apr 28 '10 at 10:15
  • The question is about the name of the interface that you call *I*DataReader and whether to call it *I*DataReader or DataReader. The question is not about classes vs. interfaces. – Thomas Lötzer Apr 28 '10 at 10:55
  • You are right, but in the question one compare `IList` with `List`. I decide to write my answer mostly to clear, that it can be sometime useful to use `IList` instead of `List`, but comparing usage of `IDataReader` with the usage of `SqlDataReader` I find easier to understand. – Oleg Apr 28 '10 at 11:14
0

I stick to the convention only because I have to, if I am to use any interfaces in the BCL and maintain consistency.

I don't like the convention, either.

xofz
  • 5,600
  • 6
  • 45
  • 63
0

Cannot believe it that so many people hate the 'I' prefix. I love the prefix 'I'. Here is why:

  • Are abstract and interface different? Yes
  • Do I care the difference as a developer? Yes, but not always.
  • When do I need to care?

Design discussion(When I draw on the board, prefix 'I' clearly telling everyone it's an interface) Read existing code(When I see prefix 'I', clearly I know it's an interface. There'are exceptions for words start with 'I', but very few cases)

  • Do I always need 'I'? No. But I want consistency, so YES.

With just one prefix 'I', it avoids so much communication overhead.

Synyong
  • 11
  • 3
0

I think the real question in case of .NET should be: why do we ever need to distinguish between a class and an interface in a client code?

And for the C# & .NET there is a shameful answer - because someone invented an explicit interface implementations language support. A thing that is in my opinion a complete mess, because it allows to break a Single Responsibility Principle in an invisible way to the caller. Lets assume we have an IList interface and a List class.

This is only by convention that List.Count() does the same thing as IList.Count() does for the class. Normally you can't be so sure. As for me explicit interface implementation is a hidden form of method overloading done in the most wrong way ever. Let's assume like in old native languages that the instance reference is a first argument of a called method.

Now we have int Count(IList list) and int Count(List list). From the language point of view these are two separate methods that clearly advertise their responsibility - one can work with a more abstract IList, and another with the specific implementation List. But this is clearly visible here! No one would expect that both methods return the same value, because the more specific method may retrieve extra properties etc. It is however non obvious in the C# language in an explicit interface implementation form, because the caller is non aware which form is actually used - compiler knows, but I as a programmer might be unaware.

Unless I know if I call a class method or an interface method! I think it is a source of this somehow stupid convention for interfaces. If you use types named without the "I" prefix - especially in method arguments and return types - you may be unaware of whether you call a class instance method or an interface method.

As a good programmer using SOLID principles you should work with interfaces all the time - as long it is possible, especially if you are aware of explicit implementations.

This is in my opinion a hidden purpose of naming C# interfaces is this way - to cover the bad design of explicit interface implementations. You may not agree, but think twice about it - how could you ever make a method overloading feature that is effectively hidden from the calling site without expecting that a naming convention will naturally appear in order to manage it?

Michael P
  • 670
  • 7
  • 23