I can't get parameter names from valuetuple via reflection in c# 7.0
Asked Answered
P

2

16

I want to Map a ValueTuple to a class using reflection. Documentation says that there is a Attribute attached to ValueTuple with parameters names (others than Item1, Item2, etc...) but I can't see any Attribute.

Disassembly shows nothing.

What's happens?

Example:

public static T ToStruct<T, T1,T2>(this ValueTuple<T1,T2> tuple) where T : struct

Via reflection can't get Item1, Item2 names to match with T fields via reflection.

Puzzlement answered 19/4, 2017 at 7:11 Comment(0)
E
22

You should have the TupleElementNames attribute on the method created by the compiler.

See this code:

public class C {
    public (int a, int b) M() {

        return (1, 2);
    }
}

Which compiles to:

[return: TupleElementNames(new string[] {
    "a",
    "b"
})]
public ValueTuple<int, int> M()
{
    return new ValueTuple<int, int>(1, 2);
}

You can get that attribute using this code:

Type t = typeof(C);
MethodInfo method = t.GetMethod(nameof(C.M));
var attr = method.ReturnParameter.GetCustomAttribute<TupleElementNamesAttribute>();

string[] names = attr.TransformNames;
Ellieellinger answered 19/4, 2017 at 7:18 Comment(5)
public static T ToStruct<T, T1>(this ValueTuple<T1,T2> tuple) where T : struct Compiler NO adds anything to Match ValueTuple<T1,T2> with TupleElementNames...Puzzlement
It is valid only to RETURN a ValueTuple. I want use a ValueTuple as Input, not outputPuzzlement
No, it is valid for method arguments too. In your code you won't have any arguments since you use the ValueType itself. If you would use the actual type it could have.Ellieellinger
There is no other possibility. I have to admit ANY valuetuple to map toPuzzlement
We can talk for very long about this, but it won't work, as already said. The ValueType itself doesn't hold that kind of information, so when you use that type, you are lost.Ellieellinger
D
12

As Patrick pointed out above, you can use reflection to inspect the tuple names used in the declaration of your method. But that gives you no information given that your ToStruct method signature shows no names. And, in any case, that gives you no information about tuples that will actually be passed into that method.

The runtime type is only ValueTuple (no names). The names only help at compile time, as syntactic sugar for ItemN.


From the design notes:

Name erasure at runtime

Importantly, the tuple field names aren't part of the runtime representation of tuples, but are tracked only by the compiler.

As a result, the field names will not be available to a 3rd party observer of a tuple instance - such as reflection or dynamic code.


You can read more about that at http://mustoverride.com/tuples_names/

Dinge answered 20/4, 2017 at 4:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.