Reputation: 21
I have this code example. And I don't get why it does not compile. It does not allow to convert from D
to A<B>
.
D
inherits A<C>
. C
inherits B
, so that would mean I should be able to pass D
into a A<B>
method argument right? I'm probably missing something obvious here.
using System.Collections.Generic;
public class Program
{
public void Main()
{
var d = new D();
Foo(d); //Cannot convert D to A<B>
}
private void Foo(A<B> bar)
{
}
}
public abstract class A<TypeB> where TypeB : B
{
public abstract List<TypeB> list { get; set; }
}
public abstract class B
{
}
public class C : B
{
}
public class D : A<C>
{
public override List<C> list { get; set; }
}
Upvotes: 2
Views: 254
Reputation: 660004
This question has been asked hundreds of times on this site.
Suppose you have a bowl of fruit. Is it a bowl of apples? An apple is a fruit, so why is a bowl of fruit not a bowl of apples? Obviously because a bowl of fruit could already contain a banana, and so is not a bowl of apples.
Suppose you have a bowl of apples. Is it a bowl of fruit? You want to say "an apple is a fruit, therefore a bowl of apples is a bowl of fruit". But this is wrong. A bowl of fruit is something you can put a banana into, and since there is an operation you can perform on a bowl of fruit that you cannot perform on a bowl of apples, a bowl of apples cannot be used in a context where a bowl of fruit is expected.
The technical name for the kind of conversion you want is a "generic covariant conversion". C# supports generic covariant conversions in only a few specific cases:
IEnumerable<T>
.You can use an IEnumerable<Apple>
in a context where IEnumerable<Fruit>
is expected because there is no way to put a banana into an IEnumerable<Fruit>
. But you cannot use your class A<Apple>
as an A<Fruit>
because the compiler is not convinced that you have prevented all possibility of another type Banana that extends Fruit being used in a method that can only accept an Apple.
Do a search on this site for "covariance and contravariance" and you will find plenty of questions about this.
Upvotes: 9