是C#4.0 Tuple协变

Ric*_*chK 11 c# tuples covariance

(我会自己检查一下,但我没有VS2010(还))

假设我有2个基本接口:

IBaseModelInterface
IBaseViewInterface
Run Code Online (Sandbox Code Playgroud)

和2个接口实现这些:

ISubModelInterface : IBaseModelInterface
ISubViewInterface : IBaseViewInterface
Run Code Online (Sandbox Code Playgroud)

如果我定义一个Tuple<IBaseModelInterface, IBaseViewInterface>我想根据返回的工厂的结果设置它Tuple<ISubModelInterface, ISubViewInterface>.

在C#3中,即使子接口实现了基本接口,我也无法做到这一点.我非常确定C#4允许我这样做,IEnumerable<IBaseModelInterface>因为我现在使用in关键字来定义协方差.因此,没有Tuple让我这样做呢?

从我(小)我理解,协方差只允许在接口上,所以这是否意味着需要一个ITuple<T1, T2>接口?这存在吗?

Jon*_*eet 12

Tuple是一个类(嗯,一个类的家族) - 它的定义是不变的.正如您稍后提到的,只有接口和委托类型支持.NET 4中的泛型差异.

没有ITuple我知道的界面.可能有一个是协变的,因为元组是不可变的,所以你只能获得API的"out"值.

  • @Jon Skeet,有一个非通用的`ITuple`接口,但它是内部的 (2认同)

Cyr*_*don 8

您可以从元组继承来创建自己的Covariant Tuple.这样你就可以避免重写自己的均等逻辑.

public interface ICovariantTuple<out T1>
{
    T1 Item1 { get; }
}
public class CovariantTuple<T1> : Tuple<T1>, ICovariantTuple<T1>
{
    public CovariantTuple(T1 item1) : base(item1) { }
}

public interface ICovariantTuple<out T1, out T2>
{
    T1 Item1 { get; }
    T2 Item2 { get; }
}
public class CovariantTuple<T1, T2> : Tuple<T1, T2>, ICovariantTuple<T1, T2>
{
    public CovariantTuple(T1 item1, T2 item2) : base(item1, item2) { }
}

etc.... for 3, 4, 5, 6, 7, 8 items
Run Code Online (Sandbox Code Playgroud)

编译失败

Tuple<Exception> item = new Tuple<ArgumentNullException>(null);
Run Code Online (Sandbox Code Playgroud)

编译成功

ICovariantTuple<Exception> item = new CovariantTuple<ArgumentNullException>(null);
Run Code Online (Sandbox Code Playgroud)

8个项目后没有基本元组,但它应该足够了.