Type cast to generic type
The following question got posted to one of the internal DLs.
Why does the following fail to compile.
public interface A { }
public class B : A { }
public class C : B { }
class D
{
public void f()
{
C c = new B() as C; // Valid!
}
public void g<T>() where T : A
{
T t = new B() as T; // Invalid! Error CS0413
}
}
The constraint (where T : A) clearly tells the compiler that T is A and B derives from A. So it should've been possible to cast B into T. However, the compiler fails with a "The type parameter 'T' cannot be used with the 'as' operator because it does not have a class type constraint nor a 'class' constraint".
If the above was possible then I would've been able to do the following
struct S1 : A { }
D d = new D();
d.g<S1>(); // meets the constraint that S1:A
This means that effective we are doing T t = new B() as S1. But the C# spec clearly calls out "In an operation of the form e as T, e must be an expression and T must be a reference type". This means that using a struct (value type) in an as statement is not allowed and would make the above illegal.
The solution is to tell the compiler that I'd only send reference types for T and you do this by
public void g<T>() where T : class, A
{
T t = new B() as T; // Invalid! Error CS0413
}