C# 访问修饰符完全指南:从默认规则到 getter/setter 粒度控制

显示原文

引言

如果在类的成员上不写任何访问修饰符,它就会默认为private。而在顶层类中如果不写任何修饰符,它则默认为internal。

class 车辆 // 如果这里没有“public”,就会默认是“internal”
{
    double _燃油; // 没有修饰符 = 隐式 private — 注意,很容易被忽略
}

所有访问级别的完整对照表,包括之前示意图中未列出的组合:

修饰符 可访问者
private 仅本类
protected 本类及其子类,在任意程序集中均可访问
internal 同一程序集(项目/DLL)中的任何代码
protected internal 子类或同一程序集(两者的并集)
private protected 子类且同时在同一程序集中(两者的交集 — C# 7.2+)
public 任何地方
file(C# 11+) 仅限于同一.cs源文件内 — 属于小众用法,多用于生成代码

应用到我们的类中:

abstract class 车辆
{
    private int _防盗警报密码 = 4821;          // 只有车辆类可见,连子类都看不到
    protected double _里程数;                   // 车辆类及其子类可见
    internal string 部队编号 = "FROTA-01";       // 同一项目的任何类都能看到
    public string 牌照 { get; }                  // 真正的任何人皆可访问
}

按访问器粒度控制——这一点常被低估:同一个属性的getter和setter可以有不同的访问级别:

public class 车辆
{
    // getter公开(所有人都能读取速度),setter私有(只有车辆类自己能修改)
    public double 当前速度 { get; private set; }

    // getter受保护且内部可见(子类或同一程序集),setter仅限子类
    protected internal double 行程表 { get; protected set; }
}

这就是你在实际代码中实现“隐藏数据、暴露受控访问”原则的方式——无需手动编写一个GetVelocidade()方法。

实用决策法则:

字段几乎总是private(如需暴露,则通过属性);仅作为内部实现细节的方法,设为private;同一模块内的其他类需要、但外部无需接触的,设为internal;属于类“公共契约”的部分,则设为public。

只有当你明确会有继承关系、且子类确实需要直接访问时,才使用protected。

添加评论
点赞收藏
点踩分享查看原文
评论
?
参与讨论