可访问性级别

public
关键字是类型和类型成员的访问修饰符。公共访问是允许的最高访问级别。
private
关键字是一个成员访问修饰符。私有访问是允许的最低访问级别。私有成员只有在声明它们的类和结构体中才是可访问的,如下例所示:
class Employee
{
private int i;
double d; // private access by default 默认的私有访问
}
在此示例中,Employee 类包含两个私有数据成员 name 和 salary。
作为私有成员,它们只能通过成员方法来访问,
因此,添加了名为 GetName 和 Salary 的公共方法,以允许对私有成员进行受控制的访问。name 成员通过公共方法来访问,salary 成员通过一个公共只读属性来访问。
// private_keyword.cs
using System;
class Employee
{
private string name = "FirstName, LastName";
private double salary = 100.0;
public string GetName()
{
return name;
}
public double Salary
{
get { return salary; }
}
}
class MainClass
{
static void Main()
{
Employee e = new Employee();
// The data members are inaccessible (private), so
// then can't be accessed like this:
// string n = e.name;
// double s = e.salary;
// 'name' is indirectly accessed via method:
string n = e.GetName();
// 'salary' is indirectly accessed via property
double s = e.Salary;
}
}
internal
关键字是类型和类型成员的访问修饰符。
只有在同一程序集的文件中
,内部类型或成员才是可访问的,如下例所示:
内部访问通常用于基于组件的开发,因为它使一组组件能够以私有方式进行合作,而不必向应用程序代码的其余部分公开。例如,用于生成图形用户界面的框架可以提供“控件”类和“窗体”类,这些类通过使用具有内部访问能力的成员进行合作。由于这些成员是内部的,它们不向正在使用框架的代码公开。
从定义具有内部访问能力的类型或成员的程序集外部引用该类型或成员是错误的。
该示例包含两个文件:Assembly1.cs 和 Assembly2.cs。第一个文件包含内部基类 BaseClass。在第二个文件中,实例化 BaseClass 的尝试将产生错误。
// Assembly1.cs
// compile with: /target:library
internal class BaseClass
{
public static int intM = 0;
}
// Assembly1_a.cs
// compile with: /reference:Assembly1.dll
class TestAccess
{
static void Main()
{
BaseClass myBase = new BaseClass(); // CS0122
}
}
在此示例中,使用与示例 1 中所用的文件相同的文件,并将 BaseClass 的可访问性级别更改为
public
。还将成员 IntM 的可访问性级别更改为
internal
。在此例中,您可以实例化类,但不能访问内部成员。
// Assembly2.cs
// compile with: /target:library
public class BaseClass
{
internal static int intM = 0;
}
// Assembly2_a.cs
// compile with: /reference:Assembly1.dll
public class TestAccess
{
static void Main()
{
BaseClass myBase = new BaseClass(); // Ok.
BaseClass.intM = 444; // CS0117
}
}
protected
关键字是一个成员访问修饰符。受保护成员
在它的类中
可访问并且可
由派生类访问
。
仅当访问通过派生类类型发生时,基类的受保护成员在派生类中才是可访问的。例如,请看以下代码段:
// protected_keyword.cs
using System;
class A
{
protected int x = 123;
}
class B : A
{
static void Main()
{
A a = new A();
B b = new B();
// Error CS1540, because x can only be accessed by
// classes derived from A.
// a.x = 10;
// OK, because this class derives from A.
b.x = 10;
}
}
结构成员无法受保护,因为无法继承结构。
一个成员或类型只能有一个访问修饰符,使用
protected internal
组合时除外。
命名空间上不允许使用访问修饰符。命名空间没有访问限制。
根据发生成员声明的上下文,只允许某些声明的可访问性。如果在成员声明中未指定访问修饰符,则使用默认的可访问性。
不嵌套在其他类型中的顶级类型的可访问性只能是
internal
或
public
。这些类型的默认可访问性是
internal
。
嵌套类型是其他类型的成员,它们可以具有下表所示的声明的可访问性。

可访问域
顶级类型的可访问域至少是声明它的项目的程序文本,即该项目的整个源文件。嵌套类型的可访问域至少是声明它的类型的程序文本,即包括任何嵌套类型的类型体。嵌套类型的可访问域决不能超出包含类型的可访问域。这些概念在以下示例中加以说明。
该示例包含一个顶级类型 T1 和两个嵌套类 M1 和 M2。这两个类包含具有不同声明的可访问性的字段。在 Main 方法中,每个语句后都有注释,指示每个成员的可访问域。注意,试图引用不可访问的成员的语句被注释掉了。如果希望查看由引用不可访问的成员所导致的编译器错误,请逐个移除注释。
public class T1
{
public static int publicInt;
internal static int internalInt;
private static int privateInt = 0; // CS0414警告 私有字段“field”已被赋值,但该值从未使用过
public class M1
{
public static int publicInt;
internal static int internalInt;
private static int privateInt = 0; // CS0414
}
private class M2
{
public static int publicInt = 0;
internal static int internalInt = 0;
private static int privateInt = 0; // CS0414
}
}
class MainClass
{
static void Main()
{
// Access is unlimited: publicInt的访问不受无限:
T1.publicInt = 1;
// Accessible only in current assembly: 仅在当前装配中可访问:
T1.internalInt = 2;
// Error: inaccessible outside T1: 不可以访问,因为它受保护级别限制 私有变量超出T1范围是无法访问的
// T1.privateInt = 3;
// Access is unlimited:
T1.M1.publicInt = 1;
// Accessible only in current assembly:
T1.M1.internalInt = 2;
// Error: inaccessible outside M1: 不可以访问,因为它受保护级别限制 私有变量超出M1范围是无法访问的
// T1.M1.privateInt = 3;
// Error: inaccessible outside T1:
// T1.M2.publicInt = 1;
// Error: inaccessible outside T1:
// T1.M2.internalInt = 2;
// Error: inaccessible outside M2:
// T1.M2.privateInt = 3;
}
}
可访问性级别的使用限制
声明类型时,最重要的是查看该类型是否必须至少与其他成员或类型具有同样的可访问性。例如,直接基类必须至少与派生类具有同样的可访问性。以下声明将导致编译器错误,因为基类 BaseClass 的可访问性小于 MyClass:
class BaseClass {...}public class MyClass: BaseClass {...} // Error
下表汇总了对使用声明的可访问性级别的限制。
