在 C# 中,访问修饰符(Access Modifiers) 用于控制类、方法、字段、属性等成员的可见性 和访问权限。作为初级 C# 工程师,掌握这些修饰符非常重要。
C# 主要有 6 种访问修饰符 ,但其中常用的有 5 个(private protected 是较新的组合)。下面我用清晰的方式为你介绍:
✅ 1. public
-
含义 :完全公开,任何地方都可以访问。
-
适用范围:类、结构、方法、字段、属性等。可以在另一个程序集中任何类访问。
-
示例 :
public class Car { public string Model; // 任何代码都能访问 }
💡 项目入口
Main方法必须是public或private(通常为public static void Main)。
✅ 2. private
-
含义 :仅限当前类内部可以访问,外部(包括子类)都无法访问。
-
默认修饰符 :类的成员(字段、方法等)如果不写访问修饰符,默认就是
private。 -
示例 :
public class BankAccount { private decimal balance = 0; // 只有 BankAccount 类内部能直接访问 public void Deposit(decimal amount) { balance += amount; // ✅ 类内部可以访问 } } // 其他类中: var account = new BankAccount(); // account.balance = 100; // ❌ 编译错误!无法访问 private 成员
✅ 3. protected
-
含义 :当前类 + 所有派生类(子类) 可以访问,其他类不行。
-
用途:常用于继承场景,让子类能访问父类的某些成员。
-
示例 :
public class Animal { protected string name; } public class Dog : Animal { public void SetName(string n) { name = n; // ✅ 子类可以访问 protected 成员 } } // 其他非子类: var animal = new Animal(); // animal.name = "Tom"; // ❌ 编译错误!不能从外部访问
✅ 4. internal
-
含义 :同一个程序集(Assembly)内 可以访问(比如同一个
.exe或.dll项目)。 -
跨项目不可见 :如果另一个项目引用了这个程序集,就无法访问
internal成员。 -
示例 :
internal class Helper { internal static void Log(string msg) { ... } }如果你的项目叫
MyApp,那么MyApp里的所有类都能访问Helper;但引用MyApp.dll的OtherApp就不能。
💡 小技巧 :可通过 [assembly: InternalsVisibleTo("FriendProject")] 让指定外部程序集也能访问 internal 成员(用于单元测试等)。
✅ 5. protected internal(组合修饰符)
- 含义 :满足
protected或internal任一条件即可访问。- 同一程序集内的任何类 ✅
- 不同程序集中的派生类 ✅
- 不是"又受保护又是内部" ,而是"受保护 或 内部"。
示例:
public class Base
{
protected internal string Info;
}
// 情况1:同一程序集中的非子类
class OtherClass
{
void Test()
{
var b = new Base();
b.Info = "OK"; // ✅ 同一程序集,可以访问
}
}
// 情况2:不同程序集中的子类
class Derived : Base
{
void Test()
{
Info = "OK"; // ✅ 是子类,即使在不同程序集也可以
}
}
✅ 6. private protected(C# 7.2 引入)
-
含义 :同一程序集中的派生类才能访问。
-
相当于
protected和internal的 交集(AND),而不是并集。 -
使用较少,但在需要严格限制继承访问时有用。
public class Base
{
private protected string Secret;
}// 同一程序集中的子类 ✅
class Derived : Base
{
void Test() => Secret = "OK";
}// 同一程序集中的非子类 ❌
class Other
{
void Test()
{
var b = new Base();
// b.Secret = "..."; // ❌ 不能访问
}
}// 不同程序集中的子类 ❌(即使继承了也不能访问)
📌 总结表
| 修饰符 | 同一类 | 同一程序集 | 派生类(同程序集) | 派生类(不同程序集) |
|---|---|---|---|---|
public |
✅ | ✅ | ✅ | ✅ |
protected |
✅ | ❌ | ✅ | ✅ |
internal |
✅ | ✅ | ✅ | ❌ |
protected internal |
✅ | ✅ | ✅ | ✅ |
private protected |
✅ | ❌ | ✅ | ❌ |
private |
✅ | ❌ | ❌ | ❌ |
🔔 注意:类本身 的访问修饰符只能是
public或internal(默认是internal)。
问题
protected 和private-protected访问修饰符有什么区别?
private-protected仅在声明程序集中可用。