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

如何正确替换泛型方法定义的System.Type[]中的泛型类型?

正确替换泛型方法定义中参数类型的泛型参数

直接调用Type.MakeGenericType会导致泛型参数映射错误,因为参数类型中的泛型参数属于方法自身的泛型定义参数,需要和传入的genericArguments按顺序一一对应,而非直接将参数类型当作泛型定义填充。

解决方案:递归替换泛型参数

实现一个工具方法,递归遍历类型结构,将方法定义中的泛型参数替换为传入的实际类型:

using System;
using System.Linq;

public static class GenericTypeResolver
{
    public static Type ResolveGenericType(Type type, Type[] methodGenericParameters, Type[] actualGenericArguments)
    {
        // 处理方法定义的泛型参数(如TOne、TTwo)
        if (type.IsGenericParameter)
        {
            int paramIndex = Array.IndexOf(methodGenericParameters, type);
            return actualGenericArguments[paramIndex];
        }

        // 处理泛型类型定义(如IDictionary<,>)
        if (type.IsGenericTypeDefinition)
        {
            Type[] resolvedArgs = type.GetGenericArguments()
                .Select(arg => ResolveGenericType(arg, methodGenericParameters, actualGenericArguments))
                .ToArray();
            return type.MakeGenericType(resolvedArgs);
        }

        // 处理已构造的泛型类型(如List<TOne>)
        if (type.IsGenericType && !type.IsGenericTypeDefinition)
        {
            Type genericDef = type.GetGenericTypeDefinition();
            Type[] resolvedArgs = type.GetGenericArguments()
                .Select(arg => ResolveGenericType(arg, methodGenericParameters, actualGenericArguments))
                .ToArray();
            return genericDef.MakeGenericType(resolvedArgs);
        }

        // 非泛型类型直接返回
        return type;
    }
}

使用方式

  1. 获取泛型方法定义的自身泛型参数:
Type[] methodGenericParams = methodInfo.GetGenericArguments();
  1. 遍历原参数类型数组,逐个替换泛型参数:
Type[] resolvedTypes = types
    .Select(t => GenericTypeResolver.ResolveGenericType(t, methodGenericParams, genericArguments))
    .ToArray();

验证测试用例

将上述代码应用到你的测试用例中:

// 原代码中获取未定义的类型数组后
Type[] types = (
    from ParameterInfo parameter
    in methodInfo.GetParameters()
    select parameter.ParameterType
).ToArray();

// 替换泛型参数
Type[] resolvedTypes = types
    .Select(t => GenericTypeResolver.ResolveGenericType(t, methodInfo.GetGenericArguments(), genericArguments))
    .ToArray();

// 输出结果
WriteLine();
WriteLine("----Resolved Generic Types:");
foreach (Type type in resolvedTypes)
    WriteLine(type);
WriteLine("----End");

输出会和invokableMethodInfo获取的结果一致:System.String。

复杂场景验证

针对你提到的void MyGenericMethod<TOne, TTwo, TThree>(IDictionary<TOne, TThree> Dictionary):

  • 方法泛型参数为[TOne, TTwo, TThree]
  • 实际传入的genericArguments为[typeof(int), typeof(string), typeof(DateTime)]
  • 替换后参数类型会正确变为IDictionary<int, DateTime>,而非错误匹配的IDictionary<int, string>。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 03:53:23