为什么将具有泛型参数的接口转换为具有较少约束的相同接口不起作用?

时间:2017-11-09 18:44:55

标签: c# generics types casting

我有这种情况:

private IHandle<ICommand> Map<T>(IHandle<T> handle)
    where T : ICommand
{
    return (IHandle<ICommand>) handle;
}

该代码给出了运行时错误。 但似乎IHandle<ICommand>IHandle<T>更通用类型(因为where T : ICommand约束)。我不明白为什么类型系统不允许这种演员。我该怎么办?

1 个答案:

答案 0 :(得分:0)

假设它是IList<T>而不是IHandle<T>。以下不起作用:

    IList<Bar> bars = new List<Bar>();
    IList<Foo> foos = (IList<Foo>)bars;

    public class Foo { }
    public class Bar : Foo { }

因为如果您尝试拨打foos.Add(new Foo());会发生什么?基础类型是Bar的列表,它不能接受任何旧的Foo添加到其中,否则它将不再是Bar的列表。其他人可能仍然可以引用它,并且需要遍历其所有元素Bar类型。所以界面必须是确切的类型。

这应该解决标题中关于为什么演员不在普通接口上工作的问题。至于&#34;你应该用它做什么&#34;,如果你保证你的界面只输出通用参数类型的东西而从不把它们作为输入,你可以通过使界面协变来使它工作,就像其他人一样建议。