4

I have 2 types, IFoo, and Foo defined as

public interface IFoo
{
    void run()
}

public class Foo : IFoo
{
    public void run() {
        // ...
    }
}

I am able to assign a List<Foo> to an IEnumerable<IFoo>, but not an ICollection<IFoo> nor an IList<IFoo>.

IEnumerable<IFoo> fooEnumerable = new List<Foo>();// works fine
ICollection<IFoo> fooCollection = new List<Foo>();// doesn't work
IList<IFoo>       fooList       = new List<Foo>();// doesn't work

Why is that? What allows an IEnumerable to not care about what type it's comprised of, while ICollection and IList do care?

Zymus
  • 1,673
  • 1
  • 18
  • 38
  • 1
    There are numerous possible duplicates. Search on c# list covariance for more. – Anthony Pegram Aug 04 '16 at 00:17
  • The basic point is that your `List` *is not* an `IList`. The former can only accept `Foo` (and Foo-derived) objects. The latter can accept *any* object that implements `IFoo`. Notice the fundamental problem (a problem which `IEnumerable` does not have). – Anthony Pegram Aug 04 '16 at 00:19
  • The problem is that if you have a reference of type IList, you could use its own interface methods to Add an object of type TextFoo, where TextFoo : IFoo. Since the actual object only accepts list items that implement Foo (which TextFoo doesn't), that won't work. – Robert Columbia Aug 04 '16 at 00:23
  • Whoever voted to re-open: please provide explanation why do you believe linked question does not answer this one. – Alexei Levenkov Aug 04 '16 at 00:55
  • @AnthonyPegram what makes IEnumerable different? – Zymus Aug 04 '16 at 01:07
  • You cannot add items to an IEnumerable. Imagine you have `IList list = new List();` *If that compiled*, there would be nothing preventing you from having `list.Add(new Orange());`. Orange is a Fruit, you have an IList of Fruit, you should be able to add it. Problem: the actual list object only holds Apples. IEnumerable, on the other hand, does not support adds. You can safely reference a list of Apples via an IEnumerable of Fruits because there's no chance you'll try to put a non-Apple into that list via the IEnumerable reference. – Anthony Pegram Aug 04 '16 at 01:24
  • @AnthonyPegram How then are we able to know that at compile time? Is there some magic "Covariant" attribute that IEnumerable has? – Zymus Aug 04 '16 at 01:34
  • 2
    Yes. Search IEnumerable. – Anthony Pegram Aug 04 '16 at 02:11
  • @AnthonyPegram Thanks for all of the info. I wasn't aware of that, and it makes things much more clear. – Zymus Aug 04 '16 at 03:57

0 Answers0