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

求助:无泛型参数下通过反射实现类型转换,解决Wrapper<T>实例化时内部类型为Object的问题

解决Wrapper类型转换的反射实现问题

我明白你的问题所在了——问题出在泛型方法的类型推断上。当你调用typedValue.BuildWrapper(...)时,typedValue的编译时类型是object,所以C#编译器会自动把BuildWrapper<T>的T推断为object,哪怕它的运行时类型是Placeholder。这就是为什么你得到的是Wrapper<Object>而不是预期的Wrapper<Placeholder>。

要解决这个问题,你需要通过反射显式调用泛型版本的BuildWrapper方法,而不是依赖编译器的类型推断。下面是修改后的ToWrapper扩展方法:

public static class HelperExtensions
{
    public static T CastTo<T>(this object o) => (T)o;

    public static List<Wrapper> ToWrapper(this IEnumerable<Helper> helperList)
    {
        List<Wrapper> wrapperResponseList = new List<Wrapper>();
        // 获取BuildWrapper泛型方法的MethodInfo
        var buildWrapperMethod = typeof(HelperExtensions)
            .GetMethod(nameof(BuildWrapper), BindingFlags.Static | BindingFlags.Public);

        foreach (var help in helperList)
        {
            if (buildWrapperMethod == null) continue;

            // 创建对应实际类型的泛型方法版本
            var genericBuildWrapper = buildWrapperMethod.MakeGenericMethod(help.Type);
            // 调用泛型方法:第一个参数是扩展方法的实例对象,后面是foo和bar参数
            var wrapper = genericBuildWrapper.Invoke(
                null,
                new object[] { help.Obj, Guid.NewGuid(), Guid.NewGuid() }
            ) as Wrapper;

            if (wrapper != null)
            {
                wrapperResponseList.Add(wrapper);
            }
        }
        return wrapperResponseList;
    }

    // 单独调用此方法可正常工作
    public static Wrapper<T> BuildWrapper<T>(this T obj, Guid foo, Guid bar)
    {
        InnerWrapper<T> inner = new InnerWrapper<T>(obj, bar);
        return new Wrapper<T>(foo, inner);
    }
}

关键修改点说明:

  1. 获取BuildWrapper的MethodInfo:因为BuildWrapper是静态扩展方法,所以从HelperExtensions类中获取它的方法信息。
  2. 创建泛型方法实例:用MakeGenericMethod传入help.Type,生成对应实际类型的BuildWrapper<T>方法。
  3. 调用泛型方法:扩展方法的本质是静态方法,第一个参数就是要扩展的实例对象(这里是help.Obj),后面跟着foo和bar的Guid参数。
  4. 类型转换:将调用结果转换为Wrapper基类,添加到列表中。

测试验证

运行你的测试代码后,你会发现生成的Wrapper实例实际类型是Wrapper<Placeholder>,而非Wrapper<Object>。你可以通过下面的代码验证:

Placeholder placeholder = new Placeholder(Guid.NewGuid());
Helper helper1 = new Helper(placeholder, placeholder.GetType());
var result = new List<Helper> { helper1 }.ToWrapper();

// 验证类型是否正确
var firstWrapper = result.First();
Console.WriteLine(firstWrapper.GetType().Name); // 输出:Wrapper`1
Console.WriteLine(firstWrapper.GetType().GenericTypeArguments[0].Name); // 输出:Placeholder

这样就能正确生成对应实际类型的Wrapper<T>实例了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 13:02:42