我无法通过c#7.0中的反射从valuetuple获取参数名称

Ram*_*eza 9 c# c#-7.0 valuetuple

我想使用反射将ValueTuple映射到类.文档说有一个属性附加到ValueTuple有参数名称(除了Item1,Item2等...)但我看不到任何属性.

反汇编没有显示任何内容.

发生什么事?

例:

public static T ToStruct<T, T1,T2>(this ValueTuple<T1,T2> tuple) where T : struct
Run Code Online (Sandbox Code Playgroud)

通过反射无法通过反射获得Item1,Item2名称与T字段匹配.

Pat*_*man 17

您应该具有TupleElementNames编译器创建的方法的属性.

看到这段代码:

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

        return (1, 2);
    }
}
Run Code Online (Sandbox Code Playgroud)

编译为:

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

您可以使用以下代码获取该属性:

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

string[] names = attr.TransformNames;
Run Code Online (Sandbox Code Playgroud)

  • 我们可以谈论这个问题很长时间,但它已经说不了.`ValueType`本身并不包含那种信息,所以当你使用那种类型时,你就会丢失. (2认同)

Jul*_*eur 8

正如Patrick上面指出的那样,您可以使用反射来检查方法声明中使用的元组名称.但是,鉴于您的ToStruct方法签名没有显示任何名称,这不会给您任何信息.并且,在任何情况下,这都不会为您提供有关实际传递给该方法的元组的信息.

运行时类型仅为ValueTuple(无名称).名称仅在编译时有用,作为语法糖ItemN.


设计说明:

在运行时命名擦除

重要的是,元组字段名称不是元组的运行时表示的一部分,而是仅由编译器跟踪.

因此,字段名称将不可用于元组实例的第三方观察者 - 例如反射或动态代码.


您可以在http://mustoverride.com/tuples_names/上阅读更多相关信息.