为什么Tuple中的TRest <t1 ... trest =“”>没有约束?</t1 ...>

时间:2010-06-08 01:00:59

标签: c# .net constraints tuples

在一个元组中,如果你有超过7个项目,你可以提供另一个元组的第8个项目,最多可以定义7个项目,然后是另一个元组作为第8个项目,然后在线上。但是,编译时第8项没有约束。例如,这是编译器的合法代码:

var tuple = new Tuple<int, int, int, int, int, int, int, double>
                (1, 1, 1, 1, 1, 1, 1, 1d);

尽管intellisense文档说TRest必须是一个元组。编写或构建代码时不会出现任何错误,直到运行时才会以ArgumentException的形式显示。

你可以在几分钟内粗略地实现一个元组,完成一个由元组约束的第8项。我只是想知道为什么它被当前的实施所取消?它是否可能是一个前向兼容性问题,他们可以使用假设的C#5添加更多元素?

粗略实施的简短版本

interface IMyTuple { }

class MyTuple<T1> : IMyTuple
{
    public T1 Item1 { get; private set; }
    public MyTuple(T1 item1) { Item1 = item1; }
}

class MyTuple<T1, T2> : MyTuple<T1>
{
    public T2 Item2 { get; private set; }
    public MyTuple(T1 item1, T2 item2) : base(item1) { Item2 = item2; }
}

class MyTuple<T1, T2, TRest> : MyTuple<T1, T2> where TRest : IMyTuple
{
    public TRest Rest { get; private set; }
    public MyTuple(T1 item1, T2 item2, TRest rest)
        : base(item1, item2)
    {
        Rest = rest;
    }
}

...

var mytuple = new MyTuple<int, int, MyTuple<int>>
                 (1, 1, new MyTuple<int>(1)); // legal
var mytuple2 = new MyTuple<int, int, int>(1, 2, 3); // illegal at compile time

2 个答案:

答案 0 :(得分:7)

这是类型系统的限制。 ITuple是一个内部接口。如果它是一个通用约束,那么它需要是公共的,然后让每个人都实现自己的ITuple,它们与元组没有任何关系。将它限制为内部允许BCL团队保证它实际上是某种元组,但导致TRest编译时安全性比它可能少。

答案 1 :(得分:1)

假设的ITuple约束不会真正将它限制为元组[1],是吗?只是一个实现ITuple

的类

[1] - 我将“元组”定义为BCL提供的Tuple<>类之一。