C#4.0元组协变吗

C#4.0元组协变吗,c#,covariance,tuples,C#,Covariance,Tuples,(我会亲自检查一下,但我还没有VS2010) 假设我有两个基本接口: IBaseModelInterface IBaseViewInterface 和2个实现这些功能的接口: ISubModelInterface : IBaseModelInterface ISubViewInterface : IBaseViewInterface 如果我定义一个元组,我想根据返回元组的工厂的结果来设置它 在C#3中,即使子接口实现了基本接口,我也不能这样做。我很确定,如果我使用IEnumerable的话,

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

假设我有两个基本接口:

IBaseModelInterface
IBaseViewInterface
和2个实现这些功能的接口:

ISubModelInterface : IBaseModelInterface
ISubViewInterface : IBaseViewInterface
如果我定义一个
元组
,我想根据返回
元组的工厂的结果来设置它

在C#3中,即使子接口实现了基本接口,我也不能这样做。我很确定,如果我使用
IEnumerable
的话,C#4可以让我这么做,因为它现在在
关键字中定义了
,允许协方差。那么
Tuple
允许我这样做吗


据我所知(很少),协方差只允许在接口上使用,那么这是否意味着需要一个
ITuple
接口?这是否存在?

Tuple
是一个类(好吧,是一个类族)——它的定义是不变的。正如您在后面提到的,在.NET4中,只有接口和委托类型支持泛型差异


我知道没有
ITuple
接口。可能有一个是协变的,因为元组是不可变的,所以您只能“从”API中获取值。

您可以从元组继承来创建自己的协变元组。这样你就避免了重写你自己的等式逻辑

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
公共接口ICOVERIANTUPLE
{
T1项1{get;}
}
公共类协变元组:元组,icovariantuple
{
公共协变元组(T1项1):基(项1){}
}
公共接口ICovariantTuple
{
T1项1{get;}
T2 Item2{get;}
}
公共类协变元组:元组,icovariantuple
{
公共协变元组(T1项1,T2项2):基(项1,项2){}
}
等对于3、4、5、6、7、8项
编译失败

Tuple<Exception> item = new Tuple<ArgumentNullException>(null);

Tuple item=新的Tuple,但它应该足够了。

我想我可以定义自己的IMyTupleneat@RichK-如果您确实打算编写自己的元组类,那么应该仔细检查BCL元组提供的比较和相等语义。我假设您希望保留与内置类中提供的相同的行为,而其中一些行为并不明显。@Jon Skeet,有一个非通用的
ITuple
接口,但它是internal@smartcaveman:是的,有,
TRest
将被检查,如果它是
ITuple
关键字允许逆变换,而不是协方差。IEnumerable被标记为out,因为T来自IEnumerable。我喜欢您的接口和伴生类解决方案!但是空工厂的目的是什么?我认为最后两个例子正好说明了什么是有效的,什么是无效的。
ICovariantTuple<Exception> item = new CovariantTuple<ArgumentNullException>(null);