You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中如何通过反射获取嵌套元组元素名称并关联元素与名称

在C#中通过反射关联嵌套元组元素与TupleElementNamesAttribute的名称

对于嵌套值元组的场景,TupleElementNamesAttribute.TransformNames返回的是扁平化的名称数组,其顺序遵循固定规则:先按顺序列出当前元组的所有顶层元素名称,再依次递归遍历每个顶层元素(若为元组类型)的内部元素名称。只要按照这个顺序递归遍历元组的类型结构,就能将每个嵌套元素和对应的名称关联起来。

规则验证

以你给出的方法为例:

public static void M(((int n1, uint n2) o1, ((int p1, (int w1, uint w2) p2, uint p3) q1, ((int x1, uint x2) r1, byte r2) q2) o2) k) {}

TransformNames数组的顺序为:"o1", "o2", "n1", "n2", "q1", "q2", "p1", "p2", "p3", "w1", "w2", "r1", "r2", "x1", "x2",对应遍历顺序:

  1. 最外层元组的顶层元素:o1、o2
  2. 递归处理o1的内部元素:n1、n2
  3. 递归处理o2的内部元素:q1、q2
  4. 递归处理q1的内部元素:p1、p2、p3
  5. 递归处理p2的内部元素:w1、w2
  6. 递归处理q2的内部元素:r1、r2
  7. 递归处理r1的内部元素:x1、x2

实现代码

以下是递归遍历元组类型并关联名称的工具类:

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.CompilerServices;

public class TupleNameMapper
{
    // 生成嵌套元组元素的路径-名称映射
    public static Dictionary<string, string> MapNestedTupleNames(Type tupleType, string[] transformNames)
    {
        var nameMap = new Dictionary<string, string>();
        var nameEnumerator = ((IEnumerable<string>)transformNames).GetEnumerator();
        
        RecurseTuple(tupleType, string.Empty, nameEnumerator, nameMap);
        return nameMap;
    }

    private static void RecurseTuple(Type type, string parentPath, IEnumerator<string> nameEnumerator, Dictionary<string, string> nameMap)
    {
        if (!IsValueTuple(type))
            return;

        // 获取当前元组的所有元素类型
        var elementTypes = type.GetGenericArguments();
        
        foreach (var elementType in elementTypes)
        {
            nameEnumerator.MoveNext();
            var elementName = nameEnumerator.Current;
            // 构建元素的完整路径(如 o1.n1)
            var fullPath = string.IsNullOrEmpty(parentPath) ? elementName : $"{parentPath}.{elementName}";
            
            nameMap[fullPath] = elementName;
            
            // 递归处理子元组
            if (IsValueTuple(elementType))
            {
                RecurseTuple(elementType, fullPath, nameEnumerator, nameMap);
            }
        }
    }

    // 判断类型是否为值元组
    private static bool IsValueTuple(Type type)
    {
        return type.IsGenericType 
               && type.GetGenericTypeDefinition().Namespace == "System" 
               && type.GetGenericTypeDefinition().Name.StartsWith("ValueTuple`", StringComparison.Ordinal);
    }
}

使用示例

public class Program
{
    public static void M(((int n1, uint n2) o1, ((int p1, (int w1, uint w2) p2, uint p3) q1, ((int x1, uint x2) r1, byte r2) q2) o2) k) {}

    public static void Main()
    {
        // 获取方法参数信息
        var methodInfo = typeof(Program).GetMethod(nameof(M));
        var parameterInfo = methodInfo.GetParameters()[0];
        var tupleAttr = parameterInfo.GetCustomAttribute<TupleElementNamesAttribute>();
        var transformNames = tupleAttr.TransformNames;
        
        // 生成映射
        var nameMap = TupleNameMapper.MapNestedTupleNames(parameterInfo.ParameterType, transformNames);
        
        // 输出结果
        foreach (var kvp in nameMap)
        {
            Console.WriteLine($"{kvp.Key}: {kvp.Value}");
        }
    }
}

输出结果

运行后会输出每个嵌套元素的完整路径和对应的名称:

o1: o1
o1.n1: n1
o1.n2: n2
o2: o2
o2.q1: q1
o2.q1.p1: p1
o2.q1.p2: p2
o2.q1.p2.w1: w1
o2.q1.p2.w2: w2
o2.q1.p3: p3
o2.q2: q2
o2.q2.r1: r1
o2.q2.r1.x1: x1
o2.q2.r1.x2: x2
o2.q2.r2: r2

内容的提问来源于stack exchange,提问作者viruseg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 14:10:12