【C#零基础从入门到精通】(二十三)——C#访问修饰符详解
在 C# 中,访问修饰符用于控制类、类成员(如字段、属性、方法等)的访问权限,一共有 6 种访问修饰符,分别是 public
、private
、protected
、internal
、protected internal
和 private protected
。下面将详细介绍它们的功能、使用方法和区别。
1. public
功能
public
是最宽松的访问修饰符,使用 public
修饰的类或成员可以被任何其他代码访问,无论这些代码位于同一个程序集还是不同的程序集。
使用方法
public class PublicClass
{
public int PublicField;
public void PublicMethod()
{
// 方法实现
}
}
在上述代码中,PublicClass
类、PublicField
字段和 PublicMethod
方法都使用了 public
修饰符,因此可以在任何地方被访问。
class Program
{
static void Main()
{
PublicClass obj = new PublicClass();
obj.PublicField = 10;
obj.PublicMethod();
}
}
2. private
功能
private
是最严格的访问修饰符,使用 private
修饰的成员只能在声明它们的类内部被访问,类外部的代码无法直接访问这些成员。
使用方法
class PrivateClass
{
private int PrivateField;
private void PrivateMethod()
{
// 方法实现
}
public void AccessPrivateMembers()
{
PrivateField = 20;
PrivateMethod();
}
}
在上述代码中,PrivateField
字段和 PrivateMethod
方法都使用了 private
修饰符,只能在 PrivateClass
类内部被访问,如 AccessPrivateMembers
方法中所示。类外部的代码无法直接访问这些私有成员。
3. protected
功能
protected
修饰的成员可以在声明它们的类内部以及该类的派生类(子类)中被访问。也就是说,protected
成员在类的继承体系内是可见的。
使用方法
class BaseClass
{
protected int ProtectedField;
protected void ProtectedMethod()
{
// 方法实现
}
}
class DerivedClass : BaseClass
{
public void AccessProtectedMembers()
{
ProtectedField = 30;
ProtectedMethod();
}
}
在上述代码中,BaseClass
中的 ProtectedField
字段和 ProtectedMethod
方法使用了 protected
修饰符,在 DerivedClass
这个派生类中可以直接访问这些 protected
成员。
4. internal
功能
internal
修饰的类或成员可以在同一个程序集(通常是一个 DLL 或 EXE 文件)内的任何代码中被访问,但在不同的程序集内无法访问。
使用方法
假设我们有一个项目包含两个类:
// 类定义在同一个程序集内
internal class InternalClass
{
internal int InternalField;
internal void InternalMethod()
{
// 方法实现
}
}
class AnotherClassInSameAssembly
{
public void AccessInternalMembers()
{
InternalClass obj = new InternalClass();
obj.InternalField = 40;
obj.InternalMethod();
}
}
在上述代码中,InternalClass
类、InternalField
字段和 InternalMethod
方法都使用了 internal
修饰符,在同一个程序集内的 AnotherClassInSameAssembly
类中可以访问这些 internal
成员。如果是不同程序集的代码,则无法访问。
5. protected internal
功能
protected internal
是 protected
和 internal
的并集,即使用 protected internal
修饰的成员可以在同一个程序集内的任何代码中被访问,也可以在不同程序集的派生类中被访问。
使用方法
// 基类定义在一个程序集内
public class BaseClassWithProtectedInternal
{
protected internal int ProtectedInternalField;
protected internal void ProtectedInternalMethod()
{
// 方法实现
}
}
// 派生类定义在同一个程序集内
class DerivedClassInSameAssembly : BaseClassWithProtectedInternal
{
public void AccessProtectedInternalMembers()
{
ProtectedInternalField = 50;
ProtectedInternalMethod();
}
}
// 派生类定义在不同程序集内
// 假设这个类在另一个程序集中引用了包含 BaseClassWithProtectedInternal 的程序集
class DerivedClassInDifferentAssembly : BaseClassWithProtectedInternal
{
public void AccessProtectedInternalMembers()
{
ProtectedInternalField = 60;
ProtectedInternalMethod();
}
}
在上述代码中,BaseClassWithProtectedInternal
类中的 ProtectedInternalField
字段和 ProtectedInternalMethod
方法使用了 protected internal
修饰符,无论是同一个程序集内的派生类 DerivedClassInSameAssembly
,还是不同程序集内的派生类 DerivedClassInDifferentAssembly
,都可以访问这些成员。同时,同一个程序集内的非派生类代码也可以访问。
6. private protected
功能
private protected
是 private
和 protected
的交集,即使用 private protected
修饰的成员只能在声明它们的类内部以及该类所在程序集内的派生类中被访问。不同程序集的派生类无法访问。
使用方法
// 基类定义在一个程序集内
public class BaseClassWithPrivateProtected
{
private protected int PrivateProtectedField;
private protected void PrivateProtectedMethod()
{
// 方法实现
}
}
// 派生类定义在同一个程序集内
class DerivedClassInSameAssembly : BaseClassWithPrivateProtected
{
public void AccessPrivateProtectedMembers()
{
PrivateProtectedField = 70;
PrivateProtectedMethod();
}
}
// 派生类定义在不同程序集内
// 假设这个类在另一个程序集中引用了包含 BaseClassWithPrivateProtected 的程序集
// 这个类无法访问 PrivateProtectedField 和 PrivateProtectedMethod
class DerivedClassInDifferentAssembly : BaseClassWithPrivateProtected
{
// 以下代码会编译错误
// public void AccessPrivateProtectedMembers()
// {
// PrivateProtectedField = 80;
// PrivateProtectedMethod();
// }
}
在上述代码中,BaseClassWithPrivateProtected
类中的 PrivateProtectedField
字段和 PrivateProtectedMethod
方法使用了 private protected
修饰符,同一个程序集内的派生类 DerivedClassInSameAssembly
可以访问这些成员,但不同程序集内的派生类 DerivedClassInDifferentAssembly
无法访问。
总结
这些访问修饰符的访问权限从宽松到严格的顺序大致为:public
> protected internal
> internal
> protected
> private protected
> private
。合理使用这些访问修饰符可以增强代码的封装性、安全性和可维护性,根据不同的需求选择合适的访问修饰符来控制类和成员的访问范围