Ion Todirel said:
exoteric said:
*snip*

how is a.Rest.Rest.Rest.Rest.Item more readable than a.Item4?

To illustrate

public struct STuple<a>
{
    private readonly a x;
    public a Some
    {
        get { return x; }
    }
    public a this[int index]
    {
        get
        {
            if (index != 0)
                throw new IndexOutOfRangeException();
            else
                return x;
        }
    }
    public IEnumerator<a> GetEnumerator()
    {
        yield return Some;
    }
    public static int Index
    {
        get { return 0; }
    }
    public static int Length
    {
        get { return Index + 1; }
    }
    public STuple(a a)
    {
        x = a;
    }
}
public struct STuple<a, b>
{
    private readonly a x;
    private readonly STuple<b> s;
    public a Some
    {
        get { return x; }
    }
    public STuple<b> Rest
    {
        get { return s; }
    }
    public dynamic this[int index]
    {
        get
        {
            if (index > Index || index < 0)
                throw new IndexOutOfRangeException();
            else
                return index == Index
                    ? Some as dynamic
                    : Rest.Some as dynamic;
        }
    }
    public IEnumerator<dynamic> GetEnumerator()
    {
        yield return Some;
        yield return Rest.Some;
    }
    public static int Index
    {
        // C# forbids: (Rest.Index + 1)
        get { return 1; }
    }
    public static int Length
    {
        get { return Index + 1; }
    }
    public STuple(a a, b b)
    {
        x = a;
        s = new STuple<b>(b);
    }
}

Example

var a = new STuple<int>(3);
var b = new STuple<int,int>(1,2);
foreach (var x in a)
    Console.WriteLine(x);
foreach (object x in b)
    Console.WriteLine(x);
Console.ReadKey();

If we could somehow express a version of GetEnumerator that only applies to a homogeneous (s)tuple, meaning (s)tuple where all type parameters are equal, then there would be no need for a dynamic formulation, esp. as this is statically known.

public static class STupleExtensions
{
    public static IEnumerator<a> GetEnumerator<a>(this STuple<a, a> s)
    {
        yield return s.Some;
        yield return s.Rest.Some;
    }
}

I realize though that this kind of trickery is probably not very high on any wishlist heh