Why List<> implements IList [duplicate]
Asked Answered
I

5

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()); 
Ihram answered 27/5, 2011 at 17:58 Comment(8)
possible duplicate of Why does List<T> implement IList<T>, ICollection<T> and IEnumerable<T>? or Why does List<T> implement all these interfaces not just IListLumbye
@Lumbye 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.Corroborate
@Lumbye I am asking about non-generic interface. But thanks for pointing that out.Ihram
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 #4817869 which has the following answer discussing backwards compatibility #4817869Solecism
@SwDevMan81: @Solecism has picked the correct duplicate. You were close, though.Weird
@Ihram - No problem. Hopefully those links will help.Lumbye
@Lumbye @Solecism you right. Thanks for the info! Voted to close.Ihram
I disagree with the close vote, since there's a particular advantage to the fact that List<T> implements non-generic IList (or more singificantly, ICollection): it makes it possible to determine the number of items in a List<Giraffe> that's passed as an IEnumerable<Animal>, without having to actually enumerate them.Maitilde
L
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.

Laurustinus answered 27/5, 2011 at 18:3 Comment(1)
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.Systole
T
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.

Tamandua answered 27/5, 2011 at 18:9 Comment(0)
P
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.

Pascasia answered 27/5, 2011 at 18:0 Comment(4)
then why not for ICollection<T> to ICollection...??Krause
It is also a great convenience when dealing with Reflection.Bisk
@Srinivas: The Collection<T> class does implement the non-generic ICollection, IList, and IEnumerable interfaces, as well.Pascasia
@Srinivas Reddy Thatiparthy - If ICollection<T> 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<T> also does not include IList.Intemperate
A
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.

Aristocrat answered 27/5, 2011 at 18:3 Comment(2)
it is trivial to implement almost all interfaces, but types do not do that. There is a greater reason behind it.Ihram
@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.Aristocrat
S
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};
Saransarangi answered 27/5, 2011 at 18:6 Comment(2)
that is an interesting answer list of lists :) However,as we figured out it is needed for the backward compatibility. Thanks for a try.Ihram
@oleksii: It's worth noting that List<T> could have implemented IList<T> in type-safe fashion if one didn't mind having IList.ReadOnly return a different value from IList<T>.ReadOnly. In other words, would could have had a mutable List<T> behave as a type-safe read-only IList.Maitilde

© 2022 - 2024 — McMap. All rights reserved.