9

我有这个简单的代码:

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>in 输入:

private static bool Synchronize(IReader<IComposite> reader)
{
    // ......
}

编译器告诉我,尽管有 T 的约束和 IReader 的协方差,但它无法从IReader<T>to转换。IReader<IComposite>

我在这里做错了什么吗?编译器应该能够验证约束并且协方差应该让我使用 my IReader<T>as IReader<Icomposite>,不是吗?

谢谢。

4

3 回答 3

5

您应该能够通过将class约束添加到T. 当涉及结构时协方差不起作用(IEnumerable<int>不能转换为IEnumerable<object>)。由于您没有被限制T为一个类,您可以传入一个IReader<some struct that implements IComposite>,它是不可转换的。

于 2012-06-20T13:15:54.453 回答
1

不幸的是没有。泛型不是协变的。IReader<T>并且IReader<IComposite>是完全不相关的类型,尽管TIComposite.

编辑: 我不知道为什么这不适用于 .Net 4 和<out T>. 其他人可以回答吗?

于 2012-06-20T12:28:47.327 回答
0

为什么不更改函数定义,因为这是您真正想要的:

private static Func<bool> MakeSynchroFunc<T>(IReader<IComposite> reader) where T : IComposite

您可能需要通用参数 T 来处理其他事情,所以我把它留在那里。

于 2012-06-20T12:30:08.330 回答