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;
}
}
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.
See more on this question at Stackoverflow