访问修饰符(C# 编程指南)
所有类型和类型成员都具有可访问性级别。 该级别可以控制是否可以从你的程序集或其他程序集中的其他代码中使用它们。 程序集是通过在单个编译中编译一个或多个 .cs 文件而创建的 .dll 或 .exe。 可以使用以下访问修饰符在进行声明时指定类型或成员的可访问性:
- public:同一程序集中的任何其他代码或引用该程序集的其他程序集都可以访问该类型或成员。 某一类型的公共成员的可访问性水平由该类型本身的可访问性级别控制。
- private:只有同一
class
或struct
中的代码可以访问该类型或成员。 - protected:只有同一
class
或者从该class
派生的class
中的代码可以访问该类型或成员。 - internal:同一程序集中的任何代码都可以访问该类型或成员,但其他程序集中的代码不可以。 换句话说,
internal
类型或成员可以从属于同一编译的代码中访问。 - protected internal:该类型或成员可由对其进行声明的程序集或另一程序集中的派生
class
中的任何代码访问。 - private protected:该类型或成员可以通过从
class
派生的类型访问,这些类型在其包含程序集中进行声明。
摘要表
调用方的位置 | public |
protected internal |
protected |
internal |
private protected |
private |
---|---|---|---|---|---|---|
在类内 | ✔️️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
派生类(相同程序集) | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ❌ |
非派生类(相同程序集) | ✔️ | ✔️ | ❌ | ✔️ | ❌ | ❌ |
派生类(不同程序集) | ✔️ | ✔️ | ✔️ | ❌ | ❌ | ❌ |
非派生类(不同程序集) | ✔️ | ❌ | ❌ | ❌ | ❌ | ❌ |
下面的示例演示如何在类型和成员上指定访问修饰符:
public class Bicycle
{
public void Pedal() { }
}
不是所有访问修饰符都可以在所有上下文中由所有类型或成员使用。 在某些情况下,类型成员的可访问性受到其包含类型的可访问性的限制。
类、记录和结构可访问性
直接在命名空间中声明的类、记录和结构(即,没有嵌套在其他类或结构中的类、记录和结构)可以为 public
或 internal
。 如果未指定任何访问修饰符,则默认设置为 internal
。
结构成员(包括嵌套的类和结构)可以声明为 public
、internal
或 private
。 类成员(包括嵌套的类和结构)可以声明为 public
、protected internal
、protected
、internal
、private protected
或 private
。 默认情况下,类成员和结构成员(包括嵌套的类和结构)的访问级别为 private
。 不能从包含类型的外部访问私有嵌套类型。
派生类和派生记录不能具有高于其基类型的可访问性。 不能声明派生自内部类 A
的公共类 B
。 如果允许这样,则它将具有使 A
公开的效果,因为可从派生类访问 A
的所有 protected
或 internal
成员。
可以通过使用 InternalsVisibleToAttribute
启用特定的其他程序集访问内部类型。 有关详细信息,请参阅友元程序集。
类、记录和结构成员可访问性
可以使用六种访问类型中的任意一种声明类和记录成员(包括嵌套的类、记录和结构)。 结构成员无法声明为 protected
、protected internal
或 private protected
,因为结构不支持继承。
通常情况下,成员的可访问性不大于包含该成员的类型的可访问性。 但是,如果内部类的 public
成员实现了接口方法或替代了在公共基类中定义的虚拟方法,则可从该程序集的外部访问该成员。
为字段、属性或事件的任何成员的类型必须至少与该成员本身具有相同的可访问性。 同样,任何方法、索引器或委托的返回类型和参数类型必须至少与该成员本身具有相同的可访问性。 例如,除非 C
也是 public
,否则不能具有返回类 C
的 public
方法 M
。 同样,如果 A
声明为 private
,则不能具有类型 A
的 protected
属性。
用户定义的运算符始终必须声明为 public
和 static
。 有关详细信息,请参阅运算符重载。
终结器不能具有可访问性修饰符。
若要设置 class
、record
或 struct
成员的访问级别,请向成员声明添加适当的关键字,如以下示例中所示。
// public class:
public class Tricycle
{
// protected method:
protected void Pedal() { }
// private field:
private int _wheels = 3;
// protected internal property:
protected internal int Wheels
{
get { return _wheels; }
}
}
其他类型
在命名空间内直接声明的接口可以声明为 public
或 internal
,就像类和结构一样,接口默认设置为 internal
访问级别。 接口成员默认为 public
,因为接口的用途是启用其他类型以访问类或结构。 接口成员声明可以包含任何访问修饰符。 这最适用于静态方法,以提供类的所有实现器需要的常见实现。
枚举成员始终为 public
,并且不能应用任何访问修饰符。
委托类似于类和结构。 默认情况下,当在命名空间内直接声明它们时,它们具有 internal
访问级别,当将它们嵌套在命名空间内时,它们具有 private
访问级别。
C# 语言规范
有关详细信息,请参阅 C# 语言规范。 该语言规范是 C# 语法和用法的权威资料。