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

C#如何仅通过Action<Class>方法修改类属性 禁止外部直接调用setter

问题原因

readonly修饰符作用在引用类型字段上时,仅限制字段本身不能被重新赋值为新的对象实例,也就是只会阻止UI.Colors = new Colors()这类写法,不会限制你通过字段拿到已有实例的引用后,调用实例上的公开setter修改属性值,这就是UI.Colors.Primary = ConsoleColor.Green依然能执行的原因。
你之前给属性set加private修饰符失效的原因也很简单:private的访问范围仅限Colors类自身内部,你的ConfigureColors方法定义在独立的UI类中,没有权限访问这些私有setter,自然两种修改方式都会报错。

实现方式

用接口隔离读写权限是最清晰的实现思路,不需要修改原有调用逻辑,就能实现读写权限控制:

  • 定义一个只包含属性getter的只读接口,作为对外暴露的类型
  • 原有Colors类作为内部实现类继承该接口,保留属性的set访问器,设置为仅程序集内部可访问
  • UI类对外只暴露只读接口类型的实例,内部持有可写的Colors实例,仅在ConfigureColors方法中传入可写实例供修改

对应代码如下:

// 对外公开的只读契约,仅包含属性读权限
public interface IReadOnlyColors
{
    ConsoleColor Primary { get; }
    ConsoleColor Default { get; }
    ConsoleColor Input { get; }
    ConsoleColor Success { get; }
    ConsoleColor Error { get; }
    ConsoleColor Highlight { get; }
}

// 内部可写的实现类,不对外部公开
internal class Colors : IReadOnlyColors
{
    public ConsoleColor Primary { get; set; } = ConsoleColor.White;
    public ConsoleColor Default { get; set; } = ConsoleColor.Gray;
    public ConsoleColor Input { get; set; } = ConsoleColor.Gray;
    public ConsoleColor Success { get; set; } = ConsoleColor.Green;
    public ConsoleColor Error { get; set; } = ConsoleColor.Red;
    public ConsoleColor Highlight { get; set; } = ConsoleColor.Blue;
}

public static class UI 
{
    // 对外暴露只读接口,外部仅能读取属性值
    public static IReadOnlyColors Colors => _colors;
    // 内部持有可写的实际实例
    private static readonly Colors _colors = new();

    public static void ConfigureColors(Action<Colors> modification) 
    {
        modification.Invoke(_colors);
    }
}

最终效果

  • 读取属性完全不受影响:var primaryColor = UI.Colors.Primary; 可正常执行
  • 通过官方配置方法修改正常可用:
    UI.ConfigureColors(colors => {
        colors.Primary = ConsoleColor.Yellow; // 正常执行
    });
    
  • 外部直接赋值会被编译器拦截:
    UI.Colors.Primary = ConsoleColor.Green; // 编译报错,IReadOnlyColors未定义set访问器
    

如果不想额外定义接口,也可以将Colors类嵌套在UI类内部,把属性setter设为UI类可访问的范围,但接口方案的隔离性更好,也不会破坏原有代码的调用习惯,是这类场景的标准实现。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 11:27:22