Question

What I would love to see in C# is better syntax around tuples eg.

var rgb = (1.0f, 1.0f, 1.0f);
// Inferred to be Tuple<float, float, float>
// Translated to var rgb = Tuple.Create(1.0f, 1.0f, 1.0f)

And

var x, y, z = rgb;

// Translated to:
//    float x = rgb.Item1;
//    float y = rgb.Item2;
//    float z = rgb.Item3;

Is there anything in the C# language which prohibits this, or makes it too difficult/unrealistic to achieve? Perhaps there are other language features which would directly clash with this?

Note that I'm not asking if this is on Microsofts radar or even if it aligns with their vision for C#, just if there are any obvious blockers to it in theory.

Edit Here are some examples from other CLI languages

// Nemerle - will use a tuple type from a language specific runtime library
def colour = (0.5f, 0.5f, 1.0f);
def (r, g, b) = colour;

// F# - Will use either a library type or `System.Tuple` depending on the framework version.
let colour = (0.5f, 0.5f, 1.0f)
let (r, g, b) = colour

// Boo - uses CLI array
def colour = (0.5, 0.5, 1.0)
def r, g, b = colour

// Cobra - uses CLI array
var colour = (0.5, 0.5, 1.0)
var r, g, b = colour

While using arrays might seem like a good compromise, it becomes limiting when mixing types eg. let a, b = (1, "one") F# or Nemerle will give us a Tuple<int, string>. In Boo or Cobra this would give us an object[].

Edit2 Language support for tuples is added in C# 7 - https://www.kenneth-truyers.net/2016/01/20/new-features-in-c-sharp-7/

Was it helpful?

Solution 3

The second syntax has been showed as non-doable by Tigran and Hilgarth.

Let's watch the first syntax:

var rgb = (1.0f, 1.0f, 1.0f);

What happen if you don't want to use the Tuple class, because instead you want to use the MyTuple class (that perhaps has the advantage of being IEnumerable<object>, something quite useful!)? Clearly that syntax won't help. You would have to put the MyTuple class somewhere...

MyTuple<float, float, float> rgb = (1.0f, 1.0f, 1.0f);

or

var rgb = new MyTuple<float, float, float>(1.0f, 1.0f, 1.0f);

now the advantage of this new shorthand syntax isn't present anymore, because somewhere you have to put the MyTuple<float, float, float>.

Note that there isn't any single collection initializer that simply "auto-discovers" everything.

var myVar = new List<int> { 1, 2, 3 };

Here the fact that we are speaking of a List<int> is quite clear :-)

Even the array initializer, that is a little "special", isn't implicit...

int[] myVar = { 1, 2, 3 };
var myVar = new[] { 1, 2, 3 };
var myVar = new int[] { 1, 2, 3 };

are all valid, but the fact that we are speaking of an array is always explicit (there is always a [])

var myVar = { 1, 2, 3 };

isn't valid :-) And the array has the "advantage" of being a primitive construct (arrays are supported directly by the IL language, while all the other collections are built on top of other .NET libraries and/or the arrays)

OTHER TIPS

The second one is not possible, because it already means something else:

float x, y, z = 0.1f;

This declares three variables x, y and z with z being initialized to 0.1. The difference to the syntax proposed in your question is subtle at best.

It's clearly a design issue as in your case you assign value only to last variable, where other two assume default values of specified type.

var x, y, z = rgb;

So whatever rgb is, only z becomes assigned to it. If you change this behavior, it would be absolutely unclear what is going on that line:

  • assignment to all variable
  • assignment only to last one

If you will not make clear decision here, it would lead to different behavior based on the type on the right side of assignment operator: in one case it would be declaration and assignment do default value, in another case declaration and assignment to specific value.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top