Generic constraint ignores co-variance

让人想犯罪 __ 提交于 2019-12-17 20:35:36

问题


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?


回答1:


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.



来源:https://stackoverflow.com/questions/46451029/generic-constraint-ignores-co-variance

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!