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

如何实现类属性修改来源检测,外部修改时自定义抛出异常

解决方案

修改后的代码

using System.Diagnostics;

public class MyClass
{
    private int position;

    public int Position
    {
        get => position;
        set
        {
            // 获取调用栈的上一帧(跳过当前set访问器的帧)
            var callerFrame = new StackTrace().GetFrame(1);
            var callerMethod = callerFrame.GetMethod();
            
            // 判断调用方是否属于当前类或其子类
            if (callerMethod.DeclaringType != GetType() && !callerMethod.DeclaringType.IsSubclassOf(GetType()))
            {
                throw new InvalidOperationException("无法从外部修改Position属性");
            }

            position = value;
        }
    }

    // 内部示例方法:可以正常修改Position
    public void UpdatePositionInternally(int newPosition)
    {
        Position = newPosition; // 不会抛出异常
    }
}

实现逻辑

  1. 放开访问限制:把原本的private set改为public set,消除编译阶段的访问拦截,允许外部代码发起赋值操作。
  2. 识别调用来源:通过StackTrace获取调用栈信息,定位发起赋值的方法所属类型:
    • 若调用方是当前类或其子类的成员,判定为内部修改,正常执行赋值;
    • 若调用方是外部类型,直接抛出InvalidOperationException异常。

注意事项

  • 性能开销:StackTrace会遍历调用栈,存在一定性能损耗,若该属性属于高频调用场景,需权衡使用;
  • 子类兼容:代码已包含子类调用的判断逻辑,若无需支持子类修改,可简化条件为callerMethod.DeclaringType != GetType();
  • 内部调用规范:类内部修改属性时,直接使用Position = 值即可,代码会自动识别为合法内部操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 06:40:14