Почему я не могу использовать "как" с параметром generic type, который ограничен интерфейсом?
В приведенном ниже примере (только для демонстрационной цели), если T
не ограничен классом, то это преобразование:
var ret = objectA as T;
.. приведет к следующей ошибке компиляции:
Параметр типа 'T' не может использоваться с оператором 'as', потому что он не имеет ограничения типа класса или ограничения класса.
Я не понимаю, почему я не могу этого сделать. Поскольку я ограничил T
интерфейсом IObject
, компилятор должен знать, что T
должен быть типом интерфейса, а операция as
должна быть действительной.
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;
}
}
Ответы
Ответ 1
так как я ограничил T интерфейсом IObject, компилятор должен знать, что T должен быть типом интерфейса, и операция "как" должна быть действительной.
Нет, T
не обязательно должен быть тип интерфейса. Он должен быть типом, который реализует интерфейс. Рассмотрим:
public struct Foo : IObject
{
public string Id { get; set; }
}
Теперь что бы вы ожидали сделать CreateObject<Foo>("ff")
?
С ограничением class
на CreateObject
этот вызов недействителен, потому что Foo
не является ссылочным типом - компилятор знает, что T
является ссылочным типом, поэтому objectA as T
в порядке.