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。
评论
?
参与讨论