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

如何为抽象类派生的子类设置受保护属性值?(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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 08:22:24