在 C# 中,访问修饰符用于控制类、结构、成员(字段、属性、方法等)的可访问范围,常见的访问修饰符有以下几种:
1. public(公共的)
可访问范围:对所有其他类和程序集都是可见的,意味着在任何引用了包含该成员的程序集的代码中,都可以访问这个成员。
示例:
public class MyClass { public int PublicField; public void PublicMethod() { Console.WriteLine("This is a public method."); } }
在其他类中可以这样访问:
class Program { static void Main() { MyClass myObj = new MyClass(); myObj.PublicField = 10; myObj.PublicMethod(); } }
2. private(私有的)
可访问范围:只能在包含该成员的类内部访问,对其他类和程序集都是不可见的。它主要用于隐藏类的内部实现细节,防止外部代码直接访问和修改。
示例:
class MyClass { private int privateField; private void PrivateMethod() { Console.WriteLine("This is a private method."); } public void AccessPrivateMembers() { privateField = 5; PrivateMethod(); } }
在外部类中,不能直接访问 privateField
和 PrivateMethod
,例如下面这样的代码会报错:
class Program { static void Main() { MyClass myObj = new MyClass(); // myObj.privateField = 10; // 编译错误,无法访问私有成员 // myObj.PrivateMethod(); // 编译错误,无法访问私有成员 myObj.AccessPrivateMembers(); } }
3. protected(受保护的)
可访问范围:在包含该成员的类及其派生类中可以访问。如果一个类从包含
protected
成员的类派生,那么派生类可以访问基类的protected
成员。示例:
class BaseClass { protected int protectedField; protected void ProtectedMethod() { Console.WriteLine("This is a protected method in base class."); } } class DerivedClass : BaseClass { public void UseProtectedMembers() { protectedField = 20; ProtectedMethod(); } }
在外部类中,不能直接访问 protectedField
和 ProtectedMethod
,只有在派生类内部才能访问:
class Program { static void Main() { DerivedClass derivedObj = new DerivedClass(); derivedObj.UseProtectedMembers(); } }
4. internal(内部的)
可访问范围:在同一程序集内的所有类都可以访问。如果一个成员被声明为
internal
,那么在其他程序集中的类就无法访问它。示例: 假设在一个名为
MyAssembly
的程序集中有如下代码:
internal class MyInternalClass { internal int InternalField; internal void InternalMethod() { Console.WriteLine("This is an internal method."); } }
在同一程序集的其他类中可以访问:
class AnotherClassInSameAssembly { static void Main() { MyInternalClass obj = new MyInternalClass(); obj.InternalField = 30; obj.InternalMethod(); } }
但在另一个不同的程序集中,尝试访问 MyInternalClass
及其成员会导致编译错误。
5. protected internal(受保护的内部的)
可访问范围:它是
protected
和internal
的组合,在同一程序集内的所有类,以及不同程序集中从包含该成员的类派生的类都可以访问。示例:
class MyClassWithProtectedInternal { protected internal int ProtectedInternalField; protected internal void ProtectedInternalMethod() { Console.WriteLine("This is a protected internal method."); } }
在同一程序集内的类可以像访问 internal
成员一样访问它;在不同程序集的派生类中,也可以访问该成员。
6. private protected(C# 7.2 引入)
可访问范围:仅限于在包含该成员的类及其派生类中访问,并且派生类必须在同一程序集内 。它提供了比
protected
更严格的访问控制。示例:
class OuterClass { private protected int PrivateProtectedField; private protected void PrivateProtectedMethod() { Console.WriteLine("This is a private protected method."); } } class InnerClassInSameAssembly : OuterClass { public void AccessPrivateProtectedMembers() { PrivateProtectedField = 40; PrivateProtectedMethod(); } }
如果在不同程序集的派生类中尝试访问 private protected
成员,将会出现编译错误。
访问修饰符 / 范围 | 当前类 | 父类 | 实例对象 | 引用当前项目的项目子类 | 引用当前项目实例对象 | 同一程序集的非子类 | 不同程序集的子类 | 不同程序集的非子类 |
---|---|---|---|---|---|---|---|---|
public | √ | √ | √ | √ | √ | √ | √ | √ |
private | √ | × | × | × | × | × | × | × |
internal | √ | √ | √ | √ | √ | √ | × | × |
protected | √ | √ | × | √ | × | × | √ | × |
protected internal | √ | √ | × | √ | √ | √ | √ | × |
private protected | √ | × | × | √ (仅同一程序集) | × | × | × (不同程序集) | × |
补充说明:
父类列:指在子类中能否访问父类中定义的成员(无论是否继承)
实例对象列:指通过对象实例访问成员(如
obj.Member
)引用当前项目的项目子类:指当前项目的子类(无论是否在同一程序集)
引用当前项目实例对象:指通过当前项目外的实例访问成员
private protected:C# 7.2+ 新增,仅允许同一程序集的子类访问
这个表格清晰展示了各访问修饰符的作用范围差异,是 C# 访问控制的重要参考工具。