2

Is it possible to declare a ValueTuple as a value in a Dictionary, and include names for the items in the ValueTuple?

I've tried:

var x = new Dictionary<String, ValueTuple<name: String, id: String> = {...}

but I didn't really expect that to work, but then neither did this:

var x = new Dictionary<String, ValueTuple<String, String>> = {
  { "mary", (name: "foo", id: "green") }}

note that the previous declaration works without mentioning name and id, but then I can't then access the tuple members by name..

var x = new Dictionary<String, ValueTuple<String, String>> = {
  { "mary", ("foo", "green") }}

var y = x["mary"].foo   // won't work
Pavel Anikhouski
  • 21,776
  • 12
  • 51
  • 66
Michael Ray Lovett
  • 6,668
  • 7
  • 27
  • 36
  • 2
    You could do this `Dictionary` – JSteward Mar 02 '20 at 20:15
  • oh! So the compiler ascertains its a ValueTuple without me naming the type! I think that's the first time I've ever seen <> accepting anything other than an explicit type.. – Michael Ray Lovett Mar 02 '20 at 20:28
  • Non-default field names for `ValueTuple` values (i.e. the names you give the fields rather than `Item1`, `Item2`, etc.) are inferred by the compiler at compile-time, used only in the context in which they can be inferred, and are not actually part of the type itself and so cannot cross an inference boundary. See e.g. https://stackoverflow.com/questions/43565738/name-valuetuple-properties-when-creating-with-new/43566072#43566072. If you want to access fields by name, then you need to stipulate the names when you use the values (e.g. via deconstruction syntax) – Peter Duniho Mar 04 '20 at 08:54

2 Answers2

3

You can use named tuples in the following way:

var dict = new Dictionary<string, (string name, string id)>();
dict.Add("Mary", ("Foo", "green"));
...
var id = dict["Mary"].id; //get an Id value

This syntax is available starting from C# 7.

If you prefer a collection initializer, you can declare a dictionary like

var dict = new Dictionary<string, (string name, string id)>
{
    { "Mary", ("Foo", "green") }
};

This declaration var y = x["mary"].foo won't work, because foo is value of tuple item, not the name. To get a foo value you should use dict["Mary"].name

Pavel Anikhouski
  • 21,776
  • 12
  • 51
  • 66
1

Yes and no.

The names are only in the code, not in the data.

You can do this:

var dict = new Dictionary<string, (string, string)>();
dict.Add("Mary", (name: "Foo", id: "green"));
(string foo, string bar) t1 = dict["Mary"];
var v1 = t1.foo; // Foo
var v2 = t1.bar; // green

While the tuple is added to the dictionary with name and id value names, it is retrieved with foo and bar value names.

Paulo Morgado
  • 14,111
  • 3
  • 31
  • 59