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

Posted by Anthony Pegram on Stack Overflow See other posts from Stack Overflow or by Anthony Pegram
Published on 2010-06-08T01:00:59Z Indexed on 2010/06/08 1:22 UTC
Read the original article Hit count: 237

Filed under:
|
|
|
|

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>
{
    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

© Stack Overflow or respective owner

Related posts about c#

Related posts about generics