C# ValueTuple properties naming
Asked Answered
C

3

12

I'm trying ValueTuple Class in C#, and i have a doubt about properties naming, let's see:

If instantiate a ValueTuple declaring the object like this: var tuple1 = (Name: "Name1", Age: 25); We can name the properties,

but, like this: ValueTuple<string,int> tuple2 = (Name: "Name1", Age: 25);

we get a warning that says the names are ignored,so

We should type: ValueTuple<string,int> tuple2 = ("Name1",25);

Then the properties will be tuple2.Item1 and tuple2.Item2

Can someone explain this newbie the reason about this?

Than you in advantage

Caren answered 6/10, 2017 at 8:35 Comment(3)
ValueTuple is just a normal C# type with no special support from the compiler. It's members are always called Item1, Item2 and so on. However, the (x, y) tuple syntax has special support from the compiler which introduces other names for the tuple members and maps them to the appropriate ValueType names in the generated IL code.Schaffer
"but, like this: ValueTuple<string,int> tuple2 = (Name: "Name1", Age: 25); we get an error" - no you don't; not on the code you've shown. You get warnings that the names in the tuple literal are effectively ignored, but you don't get an error.Diena
Possible duplicate of Name ValueTuple properties when creating with newIncapacity
D
25

There are two different "kinds" of tuples involved here: the .NET ValueTuple<...> types, and C# tuple types. C# tuple types can have element names; ValueTuple<...> types can't. (There's simply nowhere in the type system for that to live in a normal way.)

At execution time, a value is only aware of its .NET type. For example, if you use:

(string x, int y) tuple1 = ("hello", 10);
(string a, int b) tuple2 = ("hello", 10);
DoSomethingWithValue(tuple1);
DoSomethingWithValue(tuple2);
...
void DoSomethingWithValue(object value) { ... }

then DoSomethingWithValue wouldn't be able to distinguish between the two tuple values at all. The information is only available at compile-time.

Information about element names for things like parameters and return types is propagated via attributes that the C# compiler consumes. So for example, a method declared like this:

public (string name, int score) GetFoo()

is compiled in IL as if it had been declared like this:

[TupleElementNames(new string[] { "name", "score" }]
public ValueTuple<string, int> GetFoo()

The C# language defines appropriate conversions between the .NET types and the C# tuple types to make it as seamless as possible.

In terms of how to use tuples, I'd use the C# tuple types as far as you can. Naming the tuple elements makes a huge difference in usability.

Diena answered 6/10, 2017 at 9:3 Comment(1)
Thank you Jon, this helped me a lot to understand what is going on, and this C# 7 paragraph helped tooCaren
T
3

What you want to define is

(string Name,int Age) tuple1 = (Name: "Name1", Age: 25);

what you are defining is

ValueTuple<string,int> tuple2 = (Name: "Name1", Age: 25);

Look at the difference between in Type you are defining. Both are two different things if you take the name.

Truckload answered 6/10, 2017 at 8:45 Comment(4)
That does not answer the question at all - the underlying type is a ValueTuple in both cases (also the var example OP used is equivalent to your first example)Kingdom
OP wants to know why they are different. That's what I have given here as both are different types.Truckload
They ARE NOT different types. Try your code and add Console.WriteLine(tuple1.GetType().FullName); and Console.WriteLine(tuple2.GetType().FullName);Schaffer
They are different types at compile-time, but not at execution time. Just like dynamic and object.Diena
U
-1

In short: No, you can't create ValueTuples with named fields like this.

In detail: Have a look at Name ValueTuple properties when creating with new - your question is answered very well there.

Unterwalden answered 6/10, 2017 at 8:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.