Welcome to MSDN Blogs Sign in | Join | Help

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
}
Published Tuesday, July 10, 2007 2:42 PM by abhinaba
Filed under:

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# re: Type cast to generic type

Tuesday, July 10, 2007 7:02 AM by Oleg Mihailik

Well, if you unconditionally cast B to T, you would better add stronger constraint 'where T : B'.

It might be the case that you do the cast in some if/else branch. In that case you could have used brackets-cast operation:

T t = (T)((IA)new B());

There is no need for addition constraint if the logic doesn't imply that requirement.

# re: Type cast to generic type

Tuesday, July 10, 2007 8:00 AM by Wouter van Vugt

Would this work?

public void g<T>() where T : B

{

   T t = new C() as T;

}

# re: Type cast to generic type

Tuesday, July 10, 2007 12:01 PM by Oleg Mihailik

It would, for obvious reason: T still may be a struct, and 'as' operation is not allowed for structs.

# re: Type cast to generic type

Tuesday, July 10, 2007 12:01 PM by Oleg Mihailik

Sorry, I meant 'it would NOT'.

Leave a Comment

(required) 
required 
(required) 
 
Page view tracker