-1

ValueTuples allow for compiler aliases for their public fields (Item1, Item2, etc...). For example:

    var tuple = (Name:"apple",Date:DateTime.Now);
    var nameFieldValue = tuple.Name;//"apple"
    //here tuple.Name is a compiler alias for tuple.Item1

Is there any way I can do the same thing via reflection?

    var tuple = (Name:"apple",Date:DateTime.Now);
    var nameFieldValue = tuple.GetType().GetField(nameof(tuple.Name)).GetValue(tuple);//null reference exception (the field is null)

I know I can do this:

    var tuple = (Name:"apple",Date:DateTime.Now);
    var nameFieldValue = tuple.GetType().GetField("Item1").GetValue(tuple);//"apple"

But I need to get the public fields based on their compiler aliases (tuple.Name), not the actual field names (tuple.Item1).

Nigel
  • 2,961
  • 1
  • 14
  • 32
  • 1
    For a local variable, that's only present in the source code, I believe. For fields/parameters it's stored in attributes... but it's not part of the *type* itself. (You could have two different tuples with different names, but the type is identical.) – Jon Skeet Jan 20 '22 at 18:44
  • @JonSkeet Lets say I pass the tuple as a parameter to a function. How can I get the attributes of its fields to find the aliases? – Nigel Jan 20 '22 at 19:20
  • Do you mean the names from the *calling* code, or the names in the *parameter*? (Because they may be different... and you wouldn't be able to get the ones used by the calling code.) – Jon Skeet Jan 20 '22 at 19:26
  • @JonSkeet Bummer. I want the names used by the calling code. – Nigel Jan 20 '22 at 19:34

1 Answers1

2

Tuple value names are a C# language construct akin to local variables and have no existence after the code is compiled.

The compiler will translate:

var tuple = (Name:"apple",Date:DateTime.Now);
var nameFieldValue = tuple.Name;

to:

ValueTuple<string, DateTime> valueTuple = new ValueTuple<string, DateTime>("apple", DateTime.Now);
string item = valueTuple.Item1;

and if you assign that tuple to another tuple with the same structure:

var tuple = (Name:"apple",Date:DateTime.Now);
(string foo, DateTime bar) otherTuple = tuple;

the complier will just generate this code:

ValueTuple<string, DateTime> valueTuple = new ValueTuple<string, DateTime>("apple", DateTime.Now);
ValueTuple<string, DateTime> valueTuple2 = valueTuple;

Try or yourself on https://sharplab.io/

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