少于 1 分钟阅读 次阅读

在C#面向对象编程中,属性的访问控制是封装思想的核心体现。其中 { get; protected set; } 这种语法虽然简洁,却蕴含了精妙的设计哲学。它既不是完全公开的{ get; set; },也不是完全私有的字段,而是在可访问性与安全性之间找到了绝佳的平衡点。

1 语法解析:三层访问控制

1.1 基本语法结构

public bool PropertyName { get; protected set; }
  • 读取权限public get - 对所有代码开放
  • 写入权限protected set - 仅限当前类和派生类
  • 类型:可以是任意类型,不只是bool

1.2 访问级别对比表

语法形式 读取权限 写入权限 典型场景
{ get; set; } 公开 公开 普通数据载体
{ get; private set; } 公开 仅当前类 内部状态,外部只读
{ get; protected set; } 公开 当前类+派生类 继承体系中的共享状态
{ get; internal set; } 公开 同一程序集 模块内部协作
{ get; } 公开 仅初始化时 不可变属性

2 设计意图:为什么需要这样的设计?

2.1 继承体系的状态共享

在模板方法模式或基类定义通用算法时,基类需要为派生类提供可修改的”钩子”:

public abstract class DataProcessor
{
    // 派生类可以控制处理进度
    public bool IsProcessing { get; protected set; }
    
    public void Process()
    {
        IsProcessing = true;  // 基类可设置
        OnProcess();          // 调用抽象方法
        IsProcessing = false; // 基类可设置
    }
    
    protected abstract void OnProcess();
}

public class CsvProcessor : DataProcessor
{
    protected override void OnProcess()
    {
        // 处理过程中可能需要调整状态
        if (someCondition)
            IsProcessing = false;  // 派生类可设置 ✅
    }
}

2.2 状态机的受控变更

在状态模式中,状态转换应该受到严格控制:

public abstract class ConnectionState
{
    // 外部只能查询状态,只有状态类能修改
    public bool IsConnected { get; protected set; }
    
    public abstract void Handle(Connection context);
}

public class ConnectedState : ConnectionState
{
    public override void Handle(Connection context)
    {
        // 只有状态对象自己知道何时断开
        if (networkError)
            IsConnected = false;  // 状态类内部可修改
    }
}

标签:

分类:

更新时间:

留下评论