我无法通过 C# 7.0 中的反射从 valuetuple 获取参数名称
I can't get parameter names from valuetuple via reflection in c# 7.0
我想使用反射将 ValueTuple 映射到 class。
文档说有一个属性附加到带有参数名称的 ValueTuple(Item1、Item2 等除外),但我看不到任何属性。
反汇编没有显示任何内容。
发生什么事了?
示例:
public static T ToStruct<T, T1,T2>(this ValueTuple<T1,T2> tuple) where T : struct
反射无法获取Item1、Item2名称与T字段匹配
您应该在编译器创建的方法上具有 TupleElementNames
属性。
参见this code:
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;
正如帕特里克在上面指出的那样,您可以使用反射来检查方法声明中使用的元组名称。
但是,鉴于您的 ToStruct
方法签名未显示任何名称,因此不会为您提供任何信息。
而且,在任何情况下,这都不会为您提供有关实际传递给该方法的元组的信息。
运行时类型仅为 ValueTuple
(无名称)。这些名称仅在编译时有帮助,作为 ItemN
的语法糖。
来自design notes:
运行时名称擦除
重要的是,元组字段名称不是元组运行时表示的一部分,而仅由编译器跟踪。
因此,元组实例的第 3 方观察者将无法使用字段名称 - 例如 反射或动态代码。
阅读更多相关信息
我想使用反射将 ValueTuple 映射到 class。 文档说有一个属性附加到带有参数名称的 ValueTuple(Item1、Item2 等除外),但我看不到任何属性。
反汇编没有显示任何内容。
发生什么事了?
示例:
public static T ToStruct<T, T1,T2>(this ValueTuple<T1,T2> tuple) where T : struct
反射无法获取Item1、Item2名称与T字段匹配
您应该在编译器创建的方法上具有 TupleElementNames
属性。
参见this code:
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;
正如帕特里克在上面指出的那样,您可以使用反射来检查方法声明中使用的元组名称。
但是,鉴于您的 ToStruct
方法签名未显示任何名称,因此不会为您提供任何信息。
而且,在任何情况下,这都不会为您提供有关实际传递给该方法的元组的信息。
运行时类型仅为 ValueTuple
(无名称)。这些名称仅在编译时有帮助,作为 ItemN
的语法糖。
来自design notes:
运行时名称擦除
重要的是,元组字段名称不是元组运行时表示的一部分,而仅由编译器跟踪。
因此,元组实例的第 3 方观察者将无法使用字段名称 - 例如 反射或动态代码。
阅读更多相关信息