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

C#反射获取继承泛型基类私有字段值时报ArgumentException

错误根因

你遇到的ArgumentException本质是继承链遍历逻辑存在类型元数据错配问题:

  • 现有向上遍历逻辑中,只要检测到当前类型是泛型,就直接把遍历用的type变量替换为开放泛型定义(也就是DebugProperty<>)
  • 从开放泛型定义上获取到的m_value元数据,是绑定在未指定类型参数的泛型模板上的,和你实际持有的Bool实例对应的封闭泛型元数据不兼容
  • 此时调用GetValue时,运行时会校验FieldInfo绑定的声明类型和传入实例的类型是否兼容,自然抛出参数不匹配的异常
正确实现方案

修正核心逻辑:遍历继承链时始终沿着实际的封闭类型层级向上查找,只在做类型判断时临时对比泛型定义,绝对不替换遍历用的类型变量。
修正后可直接运行的代码示例:

FieldInfo field = owner.GetType().GetField(
    name, 
    BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic
);
// 提前获取字段对应的实例引用,避免重复取值
object fieldInstance = field.GetValue(owner);
Type type = field.FieldType;

// 沿实际继承链向上匹配基类
while (type != null)
{
    // 仅做判断时提取泛型定义对比,不修改遍历的type本身
    if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(DebugProperty<>))
    {
        break;
    }
    type = type.BaseType;
}

// 此时type已经是实际的DebugProperty<bool>封闭泛型类型
FieldInfo m_value = type.GetField(
    "m_value", 
    BindingFlags.Instance | BindingFlags.NonPublic
);
object val = m_value.GetValue(fieldInstance).ToString();
关键注意点
  • 之前针对直接用DebugProperty<bool>声明的字段能正常取值,是因为该场景下根本不需要向上遍历,直接从字段本身的封闭泛型类型上获取的FieldInfo天然和实例匹配,不会出现元数据错配
  • 反射操作中,从开放泛型定义获取的FieldInfo、MethodInfo等元数据,不能直接用来操作任何具体的封闭泛型实例,必须绑定到实际的封闭泛型类型上才能正常调用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.29 02:36:01