Общие ограничения и реализация интерфейса/наследование
Не совсем уверен, как сформулировать вопрос, потому что это "почему это не работает?" тип запроса.
Я уменьшил свою конкретную проблему до этого кода:
public interface IFoo
{
}
public class Foo : IFoo
{
}
public class Bar<T> where T : IFoo
{
public Bar(T t)
{
}
public Bar()
: this(new Foo()) // cannot convert from 'Foo' to 'T'
{
}
}
Теперь общий тип T
в классе Bar<T>
должен реализовать IFoo. Итак, почему компилятор дает мне ошибку в комментарии? Разумеется, экземпляр Foo является IFoo и поэтому может быть передан как представитель типичного типа T
?
Является ли это компилятором или мне что-то не хватает?
Ответы
Ответ 1
У вас также может быть Fiz, который реализует IFoo, который не связан с Foo любым другим способом:
public interface IFoo
{
}
public class Foo : IFoo
{
}
public class Fiz : IFoo
{
}
Foo foo = new Foo();
Fiz fiz = foo; // Not gonna compile.
То, что вы хотите, вероятно, больше похоже на:
public class Bar<T> where T : IFoo, new()
{
public Bar(T t)
{
}
public Bar()
: this(new T())
{
}
}
Итак, вы можете иметь
Bar<Foo> barFoo = new Bar<Foo>();
Bar<Fiz> barFiz = new Bar<Fiz>();
Ответ 2
Если вы создадите класс Baz, а затем общий тип Bar baz = new Bar(), новый Foo(), определенный как перегрузка вашего конструктора, не будет иметь тип T, в данном случае Baz.
Ответ 3
Это потому, что если вы создаете класс:
public class Fred : IFoo
{
}
И затем создайте экземпляр Bar<T>
следующим образом:
var bar = new Bar<Fred>();
Затем он нарушает ограничения класса, поскольку Foo
не является Fred
, который является текущим T
.
Вы можете заставить его скомпилировать, поместив последовательность cast (T)(IFoo)new Foo()
в конструктор, но во время выполнения вы получите InvalidCastException
, если фактический тип T
не может быть назначен из Foo
.