如果我的GenericClass
类型约束为where T : BaseType
,为什么我不能将其作为GenericClass<BaseType>
传递?
class GenericClass<T> where T : BaseType
{
void Method()
{
new UtilityClass().Method(this);
}
}
class UtilityClass
{
internal void Method(GenericClass<BaseType> genericClass)
{
}
}
静态分析器错误:
Cannot convert from 'GenericsPoc.GenericClass<T>' to
'GenericsPoc.GenericClass<GenericsPoc.BaseType>'
由于UtilityClass<T>
T
必须从BaseClass
继承,我没想到这一点。
答案 0 :(得分:4)
每天都会问这个问题。再一次!
class Cage<T> where T : Animal
{
public void Add(T t) { ... }
}
现在你的问题是:为什么这是非法的?
Cage<Animal> cage = new Cage<Gerbil>();
因为这条线是合法的:
cage.Add(new Tiger());
Cage<Animal>
有Add
方法Animal
。 Tiger
是Animal
,因此必须合法。但这意味着我们只是将一只老虎放入沙鼠笼中。
由于该行必须合法且导致类型错误,因此某些其他行必须是非法的,现在您知道它是哪一行。
您想要的功能称为通用协方差, 在C#中是合法的:
例如:
IEnumerable<Animal> animals = new List<Tiger>() { new Tiger() };
这是合法的。 List<Tiger>
实现IEnumerable<Tiger>
,这是一个接口并标记为协方差安全,因此可以将其分配给IEnumerable<Animal>
。
你会注意到没有办法将鸭子放入一系列动物,因此没有办法将鸭子放入一系列老虎中。 这就是我们如何知道它对协方差是安全的。
答案 1 :(得分:2)
您需要修改UtilityClass
,以便该方法也传递通用类型:
internal void Method<T>(GenericClass<T> genericClass) where T: BaseType
{
}