15

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

反汇编什么也没显示。

发生什么事?

例子:

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

通过反射无法得到Item1、Item2的名称来通过反射与T字段匹配。

4

2 回答 2

21

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

请参阅此代码

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

        return (1, 2);
    }
}

编译为:

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

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

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

string[] names = attr.TransformNames;
于 2017-04-19T07:18:23.510 回答
11

正如 Patrick 上面指出的,您可以使用反射来检查方法声明中使用的元组名称。但是,鉴于您的ToStruct方法签名没有显示名称,这不会为您提供任何信息。而且,无论如何,这不会为您提供有关实际传递到该方法的元组的信息。

运行时类型只是ValueTuple(无名称)。这些名称仅在编译时有帮助,作为ItemN.


设计说明

运行时名称擦除

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

因此,元组实例的第 3 方观察者将无法使用字段名称 - 例如反射或动态代码


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

于 2017-04-20T04:36:53.427 回答