Why can't I use 'as' with generic type parameter that is constrained to be an interface?

In the example below (only for demo purpose), if T is not constrained with class, then this conversion:

var ret = objectA as T;

..will cause the following compile error:

The type parameter 'T' cannot be used with the 'as' operator because it does not have a class type constraint nor a 'class' constraint.

I cannot understand why I can't do this. Since I have constrained T to be interface IObject, the compiler should know that T must be an interface type and the as operation should be valid.

public interface IObject
{
    string Id { get; set; }
}
public class ObjectA : IObject
{
    public string Id { get; set; }
}
public class ObjectFactory
{
    public T CreateObject<T>(string id) where T : IObject
    {
        ObjectA objectA = new ObjectA();
        var x = objectA as IObject; // this is good
        var ret = objectA as T; // why this 'as' cannot compile?
        return ret;
    }
    public T CreateClassObject<T>(string id) where T : class, IObject
    {
        ObjectA objectA = new ObjectA();
        var ret = objectA as T; // if T is class, this 'as' can compile
        return ret;
    }
}
Jon Skeet
people
quotationmark

since I have constrained T to be interface IObject, compiler should know that T must be an interface type and the 'as' operation should be valid.

No, T doesn't have to be an interface type. It has to be a type that implements the interface. Consider:

public struct Foo : IObject
{
    public string Id { get; set; }
}

Now what would you expect CreateObject<Foo>("ff") to do?

With the class constraint on CreateObject, that call wouldn't be valid because Foo isn't a reference type - the compiler knows that T is a reference type, so objectA as T is okay.

people

See more on this question at Stackoverflow