如何为抽象类派生的子类设置受保护属性值?(C#)
解决反射修改继承的受保护属性时抛出MissingMethodException的问题
异常原因
System.MissingMethodException的根源在于:受保护属性SomeProperty定义在基类Foo中,当你通过子类Bar的Type调用InvokeMember时,受保护成员的访问权限规则会限制这种跨类调用——尽管GetProperty能在继承链中找到该属性,但直接用子类Type执行基类受保护setter会触发权限检查失败,导致找不到对应的方法。
解决方案
方案一:通过属性定义的基类Type执行set操作
先找到属性所属的基类(即声明该属性的Foo类型),再用这个基类Type调用InvokeMember:
private void ChangeTheProtectedProperty() { var obj = new BarNamespace.Bar(); var propertyName = "SomeProperty"; var value = true; Type t = obj.GetType(); var property = t.GetProperty(propertyName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); if (property == null) throw new ArgumentOutOfRangeException(nameof(propertyName), $"Property {propertyName} was not found in Type {obj.GetType().FullName}"); // 获取属性定义的基类类型 Type declaringType = property.DeclaringType!; declaringType.InvokeMember(propertyName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.SetProperty | BindingFlags.Instance, null, obj, new object[] { value }); }
方案二:直接使用PropertyInfo.SetValue(更简洁)
无需调用InvokeMember,直接利用找到的PropertyInfo对象调用SetValue,这个方法会自动处理继承成员的访问权限:
private void ChangeTheProtectedProperty() { var obj = new BarNamespace.Bar(); var propertyName = "SomeProperty"; var value = true; Type t = obj.GetType(); var property = t.GetProperty(propertyName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); if (property == null) throw new ArgumentOutOfRangeException(nameof(propertyName), $"Property {propertyName} was not found in Type {obj.GetType().FullName}"); property.SetValue(obj, value); }
注意事项
- 单元测试中用反射修改受保护成员是常规操作,但要留意属性是否有自定义set逻辑,避免测试结果受额外逻辑影响。
- 确保测试项目具备反射访问权限(单元测试环境默认允许)。
内容的提问来源于stack exchange,提问作者Snail
相关产品推荐
相关产品推荐

