My #1 Feature Request for C# vNext: Tuple Syntax

I love the C# language. It’s clear, yet succinct. I do most of my work in it. That said, there have always been a few “nagging” things that I think would improve the C# language. My number one request for C# vNext (C#6?) is a syntax for creating Tuples easily.

F# (more appropriately OCaml in this case – but I was first exposed to it in F#) has dedicated syntax for tuples. For example:

let foo = (1, 1)

That is a tuple, which in this case is a pair of Int32s. In this case, it becomes a System.Tuple<int,int>, and the types are inferred with type inference. Functions can take tuples as arguments, too. Here is a more complete example:

let foo = (1,1)
let add (a, b) = 
    a + b
let answer = add foo

C# would need to do the syntax a little differently, but I don’t think it is far fetched. The syntax for declaring a tuple could more-or-less stay the same. I don’t believe there is any construct in C#, other than a method invocation / declaration where commas are allowed between expressions immediately within a set of parenthesis. C#’s type inference also works a lot differently, so I would imagine you would have to specify the type of the tuple explicitly if it were a method argument. For example:

This is purely fictitious syntax. 

public static void Main(string[] args)
{
    var foo = (1, 1);
    var answer = Add(foo, "Performing add");
}

private static int Add((int a, int b), string message)
{
    Console.WriteLine(message);
    return a + b;
}

I’m no Anders, so I am sure there are problems associated with that, however I think the general idea would be very useful. How it would work with other C# features like optional parameters, generics, constraints, etc. I am not so sure.

This would be a very helpful syntax when you need to return more than one thing from a method, which you can’t do with an anonymous type. For example:

private static (int * int) GetAddends()
{
    return (1, 2);
}

Currently, I would either need to construct my own return type or use Tuple.Create(1, 2). Anonymous types can’t be returned unless they are with object, and lose all type information, or as a dynamic, which just feels a little weird.