简体   繁体   English

是C#4.0元组协变

[英]Is C# 4.0 Tuple covariant

(I would check this out for myself, but I don't have VS2010 (yet)) (我会亲自检查一下,但是我还没有VS2010)

Say I have 2 base interfaces: 假设我有2个基本接口:

IBaseModelInterface
IBaseViewInterface

And 2 interfaces realizing those: 还有两个实现这些目的的接口:

ISubModelInterface : IBaseModelInterface
ISubViewInterface : IBaseViewInterface

If I define a Tuple<IBaseModelInterface, IBaseViewInterface> I would like to set that based on the result of a factory that returns Tuple<ISubModelInterface, ISubViewInterface> . 如果我定义Tuple<IBaseModelInterface, IBaseViewInterface>我想根据工厂返回Tuple<ISubModelInterface, ISubViewInterface>的结果进行设置。

In C# 3 I can't do this even though the sub interfaces realize the base interfaces. 在C#3中,即使子接口实现了基本接口,我也无法做到这一点。 And I'm pretty sure C# 4 lets me do this if I was using IEnumerable<IBaseModelInterface> because it's now defined with the in keyword to allow covariance. 而且我非常确定,如果我使用的是IEnumerable<IBaseModelInterface> C#4允许我执行此操作,因为现在已使用in关键字定义了该变量以允许协方差。 So does Tuple allow me to do this? Tuple允许我这样做吗?

From what (little) I understand, covariance is only allowed on interfaces, so does that mean there needs to be an ITuple<T1, T2> interface? 从我了解的一点(一点)来看,协方差仅在接口上被允许,是否意味着需要有一个ITuple<T1, T2>接口? Does this exist? 是否存在?

Tuple is a class (well, a family of classes) - it's invariant by definition. Tuple是一个类(嗯,一类类)-根据定义,它是不变的。 As you mention later on, only interfaces and delegate types support generic variance in .NET 4. 如您稍后所述,.NET 4中仅接口和委托类型支持通用差异。

There's no ITuple interface that I'm aware of. 我知道没有ITuple界面。 There could be one which would be covariant, as the tuples are immutable so you only get values "out" of the API. 由于元组是不可变的,因此可能会有协变,因此您只能从API之外获取值。

You can inherit from tuple for create your own Covariant Tuple. 您可以从元组继承来创建自己的协变元组。 This way you avoid to have to rewrite your own equalities logic. 这样,您就不必重写自己的相等逻辑。

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

Compile Fail 编译失败

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

Compile Success 编译成功

ICovariantTuple<Exception> item = new CovariantTuple<ArgumentNullException>(null);

There is no base Tuple after 8 items , but it should be enough. 8个项目之后没有基本的Tuple ,但是应该足够了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM