Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IEnumerable<T> conversion

Tags:

c#

Given the following:


class Base<T> {/*...*/}
class Der<T>: Base<T> {/*...*/}

interface Sth<T>{
  IEnumerable<Base<T>> Foo {get;}
}

// and implementation...
class Impl<T>: Sth<T> {
  public IEnumerable<Base<T>> Foo {
    get {
      return new List<Der<T>>();
    }
  }
}

How can I get this to compile? The error is, obviously, not implicit conversion found from List<Der<T>> to List<Base<T>>. If I cast it explicitly InvalidCastException occurs.

like image 474
SOReader Avatar asked Oct 15 '09 00:10

SOReader


2 Answers

The conversion you're trying to make isn't supported as of version 3.5 of the .NET Framework. It will be supported in version 4.0 (Visual Studio 2010) due to the addition of generic covariance/contravariance. While this will still not allow you to cast List<Der> to List<Base>, it will allow you to cast IEnumerator<Der> (which the list implements) to IEnumerator<Base>.

In the meantime, you can write your own class that implements IEnumerable<Base> and returns a custom IEnumerator<Base> that simply wraps List<Der>'s IEnumerator<Der>. Alternatively, if you are using the .NET Framework version 3.5, you can use the Cast extension method, as others have suggested.

like image 175
bcat Avatar answered Nov 15 '22 05:11

bcat


List<Der<T>> is not convertible to List<Base<T>> because the latter can have a Base<T> added to it and the former can't.

You can resolve this using the Cast extension method: return new List<Der<T>>().Cast<Base<T>>();

like image 31
itowlson Avatar answered Nov 15 '22 06:11

itowlson