1

I have the following code:

class Program
{
    static void Main(string[] args)
    {
        int a = 1;
        long b = a; //This works at runtime.

        IEnumerable<int> ints = new List<int> { 0, 1, 2, 3 };
        IEnumerable<long> longs = ints as IEnumerable<long>; //This returns null at runtime.

        Child child = new Child();
        Parent parent = child; //This works at runtime.

        IEnumerable<Child> children = new List<Child> { new Child() };
        IEnumerable<Parent> parents = children as IEnumerable<Parent>; //This returns non-null at runtime.
    }
}

public class Parent{ }

public class Child : Parent { }

If an int can be implicitly cast to a long, the same way a Child can be implicitly cast to a Parent, why does the cast not work for an IEnumerable<int> to IEnumerable<long>?

I always thought covariance made sense because you're converting one set of elements which are each individually able to be casted to another set of elements, and you're unable to add any new elements to this less derived collection meaning it's safe to cast it back again, because there was no chance of adding say a SomeOtherChild to the Parent collection.

Maybe I'm missing the point of covariance, but if what I said is right, then why doesn't covariance allow the cast from IEnumerable<int> to IEnumerable<long>?

David Klempfner
  • 8,700
  • 20
  • 73
  • 153
  • 2
    https://stackoverflow.com/questions/445471/puzzling-enumerable-cast-invalidcastexception#comment3757791_445471? – GSerg Dec 03 '19 at 22:41

1 Answers1

7

for:

public class Child : Parent {...}

A Child object is also a Parent object, no conversion necessary. An int is NOT a long; a conversion is required.

Moho
  • 15,457
  • 1
  • 30
  • 31