通用约束忽略协方差 [英] Generic constraint ignores co-variance
问题描述
public interface IEnumerable< out T>
{/*...*/}
即变体在 T
。
然后我们有另一个接口和一个实现它的类:
pre $
public interface ISomeInterface {}
public class SomeClass:ISomeInterface
{}
现在,协变量允许我们执行以下操作:
的IEnumerable< ISomeInterface> e = Enumerable.Empty< SomeClass>();
因此,一个 我们得到编译器错误CS0266 ,告诉我们 该约束清楚地表明 有没有技术上的原因,为什么这不能在一个通用的方法中工作?或者我错过的任何东西都会让编译器花费太多的代价来解决它? 更改你的 协变不支持结构,所以我们需要告诉我们只想使用类。 Let's say we have an interface like that is co-variant in Then we have another interface and a class implementing it: Now the co-variance allows us to do the following So a But if we try this in a generic method: we get the compiler error CS0266 telling us that an The constraint clearly states the Is there any technical reason why this cannot work in a generic method? Or anything I missed that makes it too expensive for the compiler to figure it out? Change your Covariance does not support structs, so we need to tell that we want to use classes only. 这篇关于通用约束忽略协方差的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! IEnumerable< SomeClass>
可赋值给 IEnumerable< ISomeInterface>
类型的变量(或方法参数)。 但是,如果我们用一个通用的方法来进行尝试:
pre $ public void GenericMethod< T>(IEnumerable< T> p)其中T: ISomeInterface
{
IEnumerable< ISomeInterface> e = p;
//或
TestMethod(p);
public void TestMethod(IEnumerable< ISomeInterface> x){}
IEnumerable< T>
不能转换为 IEnumerable< ISomeInterface> / code>。
T
是从因为
IEnumerable< T>
是 T
中的协变式,所以这个赋值应该工作(如上所示)。
GenericMethod
并添加通用约束 class
:
public void GenericMethod< T>(IEnumerable< T> p)其中T:class,ISomeInterface
{
IEnumerable< ISomeInterface> e = p;
//或
TestMethod(p);
}
public interface IEnumerable<out T>
{ /*...*/ }
T
.public interface ISomeInterface {}
public class SomeClass : ISomeInterface
{}
IEnumerable<ISomeInterface> e = Enumerable.Empty<SomeClass>();
IEnumerable<SomeClass>
is assignable to a variable (or method parameter) of type IEnumerable<ISomeInterface>
.public void GenericMethod<T>(IEnumerable<T> p) where T : ISomeInterface
{
IEnumerable<ISomeInterface> e = p;
// or
TestMethod(p);
}
public void TestMethod(IEnumerable<ISomeInterface> x) {}
IEnumerable<T>
cannot be converted to an IEnumerable<ISomeInterface>
.T
is derived from ISomeInterface
, and since IEnumerable<T>
is co-variant in T
, this assignment should work (as shown above).GenericMethod
and add generic constraint class
:public void GenericMethod<T>(IEnumerable<T> p) where T : class, ISomeInterface
{
IEnumerable<ISomeInterface> e = p;
// or
TestMethod(p);
}