开发者

Why is TRest in Tuple<T1... TRest> not constrained?

In a Tuple, if you have more than 7 items, you can provide an 8th item that is another tuple and define up to 7 items, and then another tuple as the 8th and on and on down the line. However, there is no constraint on the 8th item at compile time. For example, this is legal code for the compiler:

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

Even though the intellisense documentation says that TRest must be a Tuple. You do not get any error when writing or building the code, it does not manifest until runtime in the form of an ArgumentException.

You can roughly implement a Tuple in a few minutes, complete with a Tuple-constrained 8th item. I just wonder why it was left off the current implementation? Is it possibly a forward-compatibility issue where they could add more elements with a hypothetical C# 5?

Short version of rough implementation

interface IMyTuple { }

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

class MyTuple<T1, T2> : MyTuple<T1>
{
   开发者_Go百科 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


It's a limiation of the type system. ITuple is an internal interface. If it was a generic constraint, it would need to be public, which would then let everyone implement their own ITuple which could not have anything to do with tuples. Restricting it to internal lets the BCL team guarentee that it is actually some sort of tuple, but results in TRest being a bit less compile-time safe than it could be.


The hypothetical ITuple constraint wouldn't really constrain it to be a tuple [1], would it? Just a class that implements ITuple.

[1] - I'm defining "tuple" to be one of the BCL-provided Tuple<> classes.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜