Please look at simple code below
public class A{开发者_C百科}
public class B: A{}
public class G<T> where T : A
{
public T GetT()
{
return new A();
}
}
This code is incorrect - compiler error "Cannot convert A to return type T". But A is actually T. If I change
return new A();
to
return new A() as T;
everything is ok. What is the reason of that behavior? Thanks in advance
UPD: there was an error in initial question. Now fixed
Imagine what would happen if you did:
public class C : A{}
G<C> x = new G();
C c = x.GetT();
You really don't want that to return a B
reference...
The as
operator works because then it'll just return null
if T
isn't either B
or A
... but that's probably not really what you meant.
It's hard to know the course of action to suggest, without knowing what you're trying to do.
Reworked answer based on update
Although A
meets the generic constraint where T : A
, it's a concrete type. However, your generic class's GetT()
method has a generic return type of T
, so you have to cast your concrete type to your generic type to make the returns compatible.
The old answer holds true for your previous case of returning new B()
.
Old answer
The generic type constraint says that T
must inherit from A
; however, it does not say that T
must be B
(or a derivation of it), although B
happens to itself inherit from A
and meet the constraint.
So the return type isn't compatible (B
is always B
, but T
is not necessarily B
), and you get the error.
The same code, just with names changed
public class Animal{}
public class G<T> where T : Animal
{
public T GetT()
{
return new Animal();
}
}
Fish fish = new G<Fish>().GetT();
But GetT() doesn't return a Fish, it returns an anonymous "Animal". There's a problem : even if the contrary is true, all animals are not fish. You cannot return an Animal if a Fish is needed, and not any other kind of Animal.
where T : A
means T must inherit from A. Therefore, T
might not be an A
, so you can't just return a B
, as C
might also be inherit from A
, but a B
isn't a C
.
精彩评论