10

Possible Duplicate:
Why does (does it really?) List implement all these interfaces, not just IList?

Out of curiosity, what is the reason behind generic List<> implementing non-generic interface IList?

Sample code

IList<int> list = new List<int>();
list.Add(1);

//compiles but ArgumentException thrown at run time
((IList)list).Add(new object()); 
Community
  • 1
  • 1
oleksii
  • 35,458
  • 16
  • 93
  • 163
  • possible duplicate of [Why does List implement IList, ICollection and IEnumerable?](http://stackoverflow.com/questions/3224081/why-does-listt-implement-ilistt-icollectiont-and-ienumerablet) or [Why does List implement all these interfaces not just IList](http://stackoverflow.com/questions/4817369/why-does-does-it-really-listt-implement-all-these-interfaces-not-just-ilist) – SwDevMan81 May 27 '11 at 18:01
  • 8
    @SwDevMan81 Not really a duplicate, since that question is about the generic interfaces, while this one is for the non generic ones. EDIT: This extends to all you drive by closers. – Etienne de Martel May 27 '11 at 18:02
  • @SwDevMan81 I am asking about **non-generic** interface. But thanks for pointing that out. – oleksii May 27 '11 at 18:02
  • For backwards compatibility with pre-generics code (or code that chose to use IList rather than the generic alternative). Probably a dupe of this question http://stackoverflow.com/questions/4817369/why-does-does-it-really-listt-implement-all-these-interfaces-not-just-ilist which has the following answer discussing backwards compatibility http://stackoverflow.com/questions/4817369/why-does-does-it-really-listt-implement-all-these-interfaces-not-just-ilist/4817419#4817419 – bentayloruk May 27 '11 at 18:03
  • @SwDevMan81: @bentayloruk has picked the correct duplicate. You were close, though. – Gabe May 27 '11 at 18:05
  • @oleksii - No problem. Hopefully those links will help. – SwDevMan81 May 27 '11 at 18:09
  • @SwDevMan81 @bentayloruk you right. Thanks for the info! Voted to close. – oleksii May 27 '11 at 18:11
  • I disagree with the close vote, since there's a particular advantage to the fact that List implements non-generic IList (or more singificantly, ICollection): it makes it possible to determine the number of items in a List that's passed as an IEnumerable, without having to actually enumerate them. – supercat Jul 21 '11 at 22:19

5 Answers5

16

Take a look at this blog post by Eric Lippert: So many interfaces. He has some great insights, as always

Make sure to read the whole thing, but here's the quote that answers the question:

Why then does List implement IList?

It is a bit odd, since List for any type other than object does not fulfill the full contract of IList. It's probably to make it easier on people who are updating old C# 1.0 code to use generics; those people were probably already ensuring that only the right types got into their lists. And most of the time when you're passing an IList around, it is so the callee can get by-index access to the list, not so that it can add new items of arbitrary type.

Dyppl
  • 12,161
  • 9
  • 47
  • 68
  • Link's now broken - luckily the relevant part was quoted in the body of the answer. Unfortunately, the Wayback Machine has no copy of that blog post either. If anyone finds the post somewhere, please update the link. – alelom Oct 26 '22 at 17:16
3

IList has particular significance. In particular, it forms the hub of much data-binding, and largely acts as the canonical way of saying "I'm a bunch of items".

Note also - generics are not convenient via reflection; data-binding struggles a bit with them, preferring non-generic APIs. It helps that in the binding scenario, the convention used by the data-binding code is that if the list also has a non-object indexer:

public SomeType this[int index] {get;}

then assume the items are SomeType. Which of courseList` satisfies admirably.

So; this provides plenty of backwards compatibility with existing code and data-binding support via this.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
2

Backwards-compatibility. This way it can be injected into older frameworks/libraries That are 1.0/1.1, or were migrated from 1.0/1.1 and not fully refactored, or used with objects in the 2.0+ .Net frameworks that still sport the same interfaces they did in 1.0/1.1, without having to forgo type-safety in your new code.

Toby
  • 7,354
  • 3
  • 25
  • 26
  • then why not for ICollection to ICollection...?? – Srinivas Reddy Thatiparthy May 27 '11 at 18:01
  • 1
    It is also a great convenience when dealing with Reflection. – leppie May 27 '11 at 18:03
  • @Srinivas: The Collection *class* does implement the non-generic ICollection, IList, and IEnumerable interfaces, as well. – Toby May 27 '11 at 18:05
  • 2
    @Srinivas Reddy Thatiparthy - If `ICollection` included `ICollection`, then that would *require* generic collections to implement the non-generic interface. Such a requirement is unnecessary and cumbersome. This is a different circumstance than what is in the original question. `IList` also does not include `IList`. – Jeffrey L Whitledge May 27 '11 at 18:07
1

I believe List implements a version of IList because it is trivial to do, and may be useful, as you wouldn't need to wrap your list in another to pass it into another class.

However it does do a type-check on any items you attempt to add and will throw if they don't match.

Guvante
  • 18,775
  • 1
  • 33
  • 64
  • it is *trivial* to implement almost all interfaces, but types do not do that. There is a greater reason behind it. – oleksii May 27 '11 at 18:21
  • @oleksii: My original response was based on it being a read-only version, so was attempting to exemplify that "Why not" would be sufficient logic. Should have edited once I realized it was read-write to better wording, but there is another response available so it is a moot point. – Guvante May 27 '11 at 21:47
0

The reason is for you to be able to have a List of ILists of different types. For example -

List<int> ints = new List<int>();
List<string> strings = new List<string>();

List<IList> lists = new List<IList> { ints, strings};
Maxim
  • 7,268
  • 1
  • 32
  • 44
  • that is an interesting answer list of lists :) However,as we figured out it is needed for the backward compatibility. Thanks for a try. – oleksii May 27 '11 at 18:15
  • @oleksii: It's worth noting that `List` could have implemented `IList` in type-safe fashion if one didn't mind having `IList.ReadOnly` return a different value from `IList.ReadOnly`. In other words, would could have had a mutable `List` behave as a type-safe read-only `IList`. – supercat Nov 19 '12 at 19:02