如何通过反射获取C#泛型抽象基类中的readonly私有字段值
问题原因
报错的核心原因是你使用了开放泛型类型(未填充泛型参数的Base<,>)获取字段元数据,此状态下的FieldInfo关联的类型包含未绑定的泛型参数,无法直接用于已经构造完成的派生类实例的反射操作。
解决方法
该需求完全可以实现,只需改成从派生类对应的闭合泛型基类(已经绑定了具体泛型参数的Base<ClassC, ClassD>)获取字段元数据即可,修正后的代码如下:
var derived = new Derived(); // 直接从派生类类型获取已经绑定完泛型参数的闭合基类 var closedBaseType = derived.GetType().BaseType; // 仅保留必要的绑定标志:实例、非公开,多余的Static、FlattenHierarchy可移除避免干扰 var classCField = closedBaseType.GetField( "_classC", BindingFlags.NonPublic | BindingFlags.Instance ); // 此时GetValue可正常执行 var classCValue = classCField.GetValue(derived);
兼容多继承场景的扩展方案
如果不确定派生类的继承层级,可循环向上查找所有基类,直到匹配到泛型定义为typeof(Base<,>)的闭合基类,适配性更强:
var derived = new Derived(); Type currentType = derived.GetType(); while (currentType != null && (!currentType.IsGenericType || currentType.GetGenericTypeDefinition() != typeof(Base<,>))) { currentType = currentType.BaseType; } if (currentType == null) { throw new InvalidOperationException("实例不属于Base<,>的派生类"); } var classCField = currentType.GetField("_classC", BindingFlags.NonPublic | BindingFlags.Instance); var classCValue = classCField.GetValue(derived);
内容的提问来源于stack exchange,提问作者Józef Podlecki
相关产品推荐
相关产品推荐

