我有这个简单的代码:
public interface IReader<out T>
{
IEnumerable<T> GetData();
}
这个接口在 T 上应该是协变的,我这样使用它:
private static Func<bool> MakeSynchroFunc<T>(IReader<T> reader) where T : IComposite
{
return () => Synchronize(reader);
}
请注意 T 实现 IComposite 的约束。同步方法在输入中采用IReader<IComposite>
:
private static bool Synchronize(IReader<IComposite> reader)
{
// ......
}
编译器告诉我,尽管对 T 有约束和 IReader 的协方差,但它无法从 IReader<T>
转换为 IReader<IComposite>
。
我在这里做错了什么吗?编译器应该能够验证约束,协方差应该让我使用我的IReader<T>
作为IReader<Icomposite>
,不是吗?
谢谢。
您应该能够通过向T
添加class
约束来解决您的问题。 当涉及结构时,协方差不起作用(IEnumerable<int>
不能转换为IEnumerable<object>
)。 由于您没有将T
约束为一个类,因此您可以传入一个不可转换的IReader<some struct that implements IComposite>
。
不幸的是不是。 泛型不是协变的。 IReader<T>
和IReader<IComposite>
是完全不相关的类型,尽管T
与IComposite
有关。
编辑:我不知道为什么这不适用于.Net 4和<out T>
。其他人可以回答吗?
为什么不更改函数定义,因为这是您真正想要的:
private static Func<bool> MakeSynchroFunc<T>(IReader<IComposite> reader) where T : IComposite
您可能需要通用参数 T 来处理其他事情,所以我把它留在那里。