This has been bothering me for a while. I’m having a little trouble understanding why explicit casts are needed in the following code:
public static class CastStrangeness
{
public class A
{
}
public class B
: A
{
}
public static void Foo<T>(T item)
where T : A
{
// Works.
A fromTypeParameter = item;
// Does not compile without an explicit cast.
T fromConcreteType = (T)fromTypeParameter;
// Does not compile without an explicit cast.
Foo<T>((T)fromTypeParameter);
}
public static void Bar(A item)
{
// Compiles.
Foo<A>(item);
}
}
It seems to me that T is guaranteed to be an A, so surely the compiler could infer that any instance of A is guaranteed to be assignable to T? Otherwise, I wouldn’t be able to pass an A or a B into Foo(). So what am I missing?
PS. I’ve tried searching for endless permutations of keywords on this, but every result seems to wind up referring to covariance and contravariance WRT generic interfaces 🙂
Take the case of:
Your first assignment is ok:
Since B : A.
But this assignment is not ok:
Because you could very well have assigned fromTypeParameter as:
Which you obviously cannot cast to T (which is B in this instance). T is more specific than A, it could be derived from A. So you can go one way but not the other, without an explicit cast (which may fail).