协方差/逆变:如何编译以下代码

时间:2012-02-20 15:32:19

标签: c# generics c#-4.0 covariance

更新:以下代码仅适用于C#4.0(Visual Studio 2010)

似乎我对协方差/逆变事有一些误解。谁能告诉我为什么以下代码无法编译?

public class TestOne<TBase>
{
    public IEnumerable<TBase> Method<TDerived>(IEnumerable<TDerived> values)
        where TDerived: TBase
    {
        return values;
    }
}

虽然这个编译:( !!!)

public interface IBase
{
}
public interface IDerived: IBase
{
}
public class TestTwo
{
    public IEnumerable<IBase> Method(IEnumerable<IDerived> values)
    {
        return values;
    }
}

3 个答案:

答案 0 :(得分:13)

协方差仅适用于引用类型(对于类型参数),因此您必须添加类约束:

public IEnumerable<TBase> Method<TDerived>(IEnumerable<TDerived> values)
    where TDerived : class, TBase
{
    return values;
}

这会阻止您尝试将IEnumerable<int>转换为无效的IEnumerable<object>

答案 1 :(得分:1)

我无法想到你确实需要TDerived的任何情况。使用TBase就足够了:

public class TestOne<TBase>
{
    public IEnumerable<TBase> Method(IEnumerable<TBase> values)
    {
        return values;
    }
}

毕竟,除TDerived之外,您没有关于TBase的信息......

答案 2 :(得分:0)

最初都没有为我编译。从Super(T / I)到Base(T / I)的隐式演员都失败了。然而,当我添加一个明确的案例时,都编译了。

public IEnumerable<TBase> Method<TSuper>(IEnumerable<TSuper> values)
    where TSuper: TBase
    {
        return (IEnumerable<TBase>) values;
    }