C#的访问修饰符用于限定类、结构体、接口以及它们的成员的可访问范围,是面向对象编程中封装特性的重要实现方式,合理设置访问修饰符可以有效控制代码的暴露程度,减少不必要的耦合。

C#五种访问修饰符基础定义
C#中共有五种访问修饰符,分别是public、private、protected、internal、protected internal,每个修饰符的作用范围有明确的规定,下面逐一说明。
1. public 访问修饰符
public是最开放的访问修饰符,被它修饰的成员可以被任何程序集中的任何代码访问,没有访问限制。
// 定义一个公共类
public class PublicClass
{
// 公共字段,任何地方都可以访问
public string PublicField = "公共字段内容";
// 公共方法,任何地方都可以调用
public void PublicMethod()
{
Console.WriteLine("这是公共方法");
}
}
// 另一个程序集中的类访问PublicClass
public class OtherClass
{
public void Test()
{
PublicClass pc = new PublicClass();
Console.WriteLine(pc.PublicField); // 可以正常访问
pc.PublicMethod(); // 可以正常调用
}
}
2. private 访问修饰符
private是最严格的访问修饰符,被它修饰的成员只能在当前类的内部访问,即使是同一个程序集中的其他类也无法访问。
public class PrivateClass
{
// 私有字段,只能在PrivateClass内部访问
private string PrivateField = "私有字段内容";
// 私有方法,只能在PrivateClass内部调用
private void PrivateMethod()
{
Console.WriteLine("这是私有方法");
}
// 类内部的公共方法可以访问私有成员
public void AccessPrivateMember()
{
Console.WriteLine(PrivateField); // 内部可以访问
PrivateMethod(); // 内部可以调用
}
}
public class TestClass
{
public void Test()
{
PrivateClass pc = new PrivateClass();
// Console.WriteLine(pc.PrivateField); // 编译错误,无法访问私有字段
// pc.PrivateMethod(); // 编译错误,无法调用私有方法
pc.AccessPrivateMember(); // 可以通过公共方法间接访问
}
}
3. protected 访问修饰符
protected修饰的成员可以在当前类内部以及当前类的派生类中访问,与当前类同程序集但无继承关系的类无法访问。
public class BaseClass
{
// 受保护字段,基类和派生类可以访问
protected string ProtectedField = "受保护字段内容";
// 受保护方法,基类和派生类可以调用
protected void ProtectedMethod()
{
Console.WriteLine("这是受保护方法");
}
}
public class DerivedClass : BaseClass
{
public void Test()
{
Console.WriteLine(ProtectedField); // 派生类可以访问基类的受保护字段
ProtectedMethod(); // 派生类可以调用基类的受保护方法
}
}
public class UnrelatedClass
{
public void Test()
{
BaseClass bc = new BaseClass();
// Console.WriteLine(bc.ProtectedField); // 编译错误,无继承关系的类无法访问
}
}
4. internal 访问修饰符
internal修饰的成员只能在当前程序集内部访问,其他程序集的代码无法访问,不管是否有继承关系。
// 当前程序集内的类
internal class InternalClass
{
// 内部字段,当前程序集内可以访问
internal string InternalField = "内部字段内容";
// 内部方法,当前程序集内可以调用
internal void InternalMethod()
{
Console.WriteLine("这是内部方法");
}
}
// 同一个程序集内的其他类
public class SameAssemblyClass
{
public void Test()
{
InternalClass ic = new InternalClass();
Console.WriteLine(ic.InternalField); // 可以正常访问
ic.InternalMethod(); // 可以正常调用
}
}
// 如果是其他程序集引用当前程序集,将无法访问InternalClass及其成员
5. protected internal 访问修饰符
protected internal是protected和internal的并集,被它修饰的成员可以在当前程序集内部访问,或者在其他程序集中的派生类中访问。
public class ProtectedInternalClass
{
// 受保护内部字段
protected internal string ProtectedInternalField = "受保护内部字段内容";
// 受保护内部方法
protected internal void ProtectedInternalMethod()
{
Console.WriteLine("这是受保护内部方法");
}
}
// 同一个程序集内的类
public class SameAssemblyTest
{
public void Test()
{
ProtectedInternalClass pc = new ProtectedInternalClass();
Console.WriteLine(pc.ProtectedInternalField); // 可以访问
pc.ProtectedInternalMethod(); // 可以调用
}
}
// 其他程序集中的派生类
public class OtherAssemblyDerivedClass : ProtectedInternalClass
{
public void Test()
{
Console.WriteLine(ProtectedInternalField); // 派生类可以访问
ProtectedInternalMethod(); // 派生类可以调用
}
}
五种访问修饰符作用范围对比
为了更清晰地对比五种访问修饰符的作用范围,整理如下表格:
| 访问修饰符 | 同一类内部 | 同一程序集派生类 | 同一程序集非派生类 | 不同程序集派生类 | 不同程序集非派生类 |
|---|---|---|---|---|---|
| public | 可以 | 可以 | 可以 | 可以 | 可以 |
| private | 可以 | 不可以 | 不可以 | 不可以 | 不可以 |
| protected | 可以 | 可以 | 不可以 | 可以 | 不可以 |
| internal | 可以 | 可以 | 可以 | 不可以 | 不可以 |
| protected internal | 可以 | 可以 | 可以 | 可以 | 不可以 |
访问修饰符使用建议
在实际开发中,建议遵循最小权限原则,即成员的访问权限尽可能设置得小,不需要暴露给外部的成员就不要用public修饰。类的字段通常设置为private,通过公共的属性来暴露访问接口,这样可以在属性的get和set方法中添加额外的逻辑,比如数据校验。如果成员只需要在当前程序集内部使用,就使用internal修饰,避免被其他程序集误调用。需要被派生类重写或者访问的成员,使用protected修饰即可。