通用约束忽略协方差 [英] Generic constraint ignores co-variance

查看:128
本文介绍了通用约束忽略协方差的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我们有一个接口,如

  public interface IEnumerable< out T> 
{/*...*/}

变体在 T



然后我们有另一个接口和一个实现它的类:



pre $ public interface ISomeInterface {}
public class SomeClass:ISomeInterface
{}

现在,协变量允许我们执行以下操作:

 的IEnumerable< ISomeInterface> e = Enumerable.Empty< SomeClass>(); 

因此,一个 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){}

我们得到编译器错误CS0266 ,告诉我们 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);
}

协变不支持结构,所以我们需要告诉我们只想使用类。


Let's say we have an interface like

public interface IEnumerable<out T>
{ /*...*/ }

that is co-variant in T.

Then we have another interface and a class implementing it:

public interface ISomeInterface {}
public class SomeClass : ISomeInterface
{}

Now the co-variance allows us to do the following

IEnumerable<ISomeInterface> e = Enumerable.Empty<SomeClass>();

So a IEnumerable<SomeClass> is assignable to a variable (or method parameter) of type IEnumerable<ISomeInterface>.

But if we try this in a generic method:

public void GenericMethod<T>(IEnumerable<T> p) where T : ISomeInterface
{
    IEnumerable<ISomeInterface> e = p;
    // or
    TestMethod(p);
}
public void TestMethod(IEnumerable<ISomeInterface> x) {}

we get the compiler error CS0266 telling us that an IEnumerable<T> cannot be converted to an IEnumerable<ISomeInterface>.

The constraint clearly states the T is derived from ISomeInterface, and since IEnumerable<T> is co-variant in T, this assignment should work (as shown above).

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 GenericMethod and add generic constraint class:

public void GenericMethod<T>(IEnumerable<T> p) where T : class, ISomeInterface
{
    IEnumerable<ISomeInterface> e = p;
    // or
    TestMethod(p);
}

Covariance does not support structs, so we need to tell that we want to use classes only.

这篇关于通用约束忽略协方差的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆