访问修饰符(C# 编程指南)Access Modifiers (C# Programming Guide)

所有类型和类型成员都具有可访问性级别,该级别可以控制是否可以从你的程序集或其他程序集中的其他代码中使用它们。All types and type members have an accessibility level, which controls whether they can be used from other code in your assembly or other assemblies. 可以使用以下访问修饰符在进行声明时指定类型或成员的可访问性:You can use the following access modifiers to specify the accessibility of a type or member when you declare it:

publicpublic
同一程序集中的任何其他代码或引用该程序集的其他程序集都可以访问该类型或成员。The type or member can be accessed by any other code in the same assembly or another assembly that references it.

privateprivate
只有同一类或结构中的代码可以访问该类型或成员。The type or member can be accessed only by code in the same class or struct.

受保护protected
只有同一类或者从该类派生的类中的代码可以访问该类型或成员。The type or member can be accessed only by code in the same class, or in a class that is derived from that class.
internalinternal
同一程序集中的任何代码都可以访问该类型或成员,但其他程序集中的代码不可以。The type or member can be accessed by any code in the same assembly, but not from another assembly.

受保护的内部 该类型或成员可由对其进行声明的程序集或另一程序集中的派生类中的任何代码访问。protected internal The type or member can be accessed by any code in the assembly in which it is declared, or from within a derived class in another assembly.

专用受保护只有在其声明程序集内,通过相同类中的代码或派生自该类的类型,才能访问类型或成员。private protected The type or member can be accessed only within its declaring assembly, by code in the same class or in a type that is derived from that class.

下面的示例演示如何在类型和成员上指定访问修饰符:The following examples demonstrate how to specify access modifiers on a type and member:

public class Bicycle
{
    public void Pedal() { }
}

并非所有的访问修饰符都可以由所有上下文中的所有类型或成员使用,并且在某些情况下,类型成员的可访问性受其包含类型的可访问性限制。Not all access modifiers can be used by all types or members in all contexts, and in some cases the accessibility of a type member is constrained by the accessibility of its containing type. 以下各节提供了有关可访问性的更多详细信息。The following sections provide more details about accessibility.

类和结构可访问性Class and Struct Accessibility

在命名空间内直接声明(换句话说,不嵌套在其他类或结构中)的类和结构可以为公共或内部。Classes and structs that are declared directly within a namespace (in other words, that are not nested within other classes or structs) can be either public or internal. 如果未指定任何访问修饰符,则默认设置为内部。Internal is the default if no access modifier is specified.

结构成员(包括嵌套的类和结构)可以声明为公共、内部或私有。Struct members, including nested classes and structs, can be declared as public, internal, or private. 类成员(包括嵌套的类和结构)可以为公共、受保护的内部、受保护、内部、专用受保护或专用。Class members, including nested classes and structs, can be public, protected internal, protected, internal, private protected or private. 默认情况下,类成员和结构成员(包括嵌套的类和结构)的访问级别为私有。The access level for class members and struct members, including nested classes and structs, is private by default. 不能从包含类型的外部访问私有嵌套类型。Private nested types are not accessible from outside the containing type.

派生类不能具有高于其基类型的可访问性。Derived classes cannot have greater accessibility than their base types. 换而言之,不能具有派生自内部类 A 的公共类 BIn other words, you cannot have a public class B that derives from an internal class A. 如果允许这样,则它将具有使 A 公开的效果,因为可从派生类访问 A 的所有受保护的或内部成员。If this were allowed, it would have the effect of making A public, because all protected or internal members of A are accessible from the derived class.

可以通过使用 InternalsVisibleToAttribute 启用特定的其他程序集访问内部类型。You can enable specific other assemblies to access your internal types by using the InternalsVisibleToAttribute. 有关详细信息,请参阅友元程序集For more information, see Friend Assemblies.

类和结构成员可访问性Class and Struct Member Accessibility

可以使用六种访问类型中的任意一种声明类成员(包括嵌套的类和结构)。Class members (including nested classes and structs) can be declared with any of the six types of access. 结构成员无法声明为受保护,因为结构不支持继承。Struct members cannot be declared as protected because structs do not support inheritance.

通常情况下,成员的可访问性不大于包含该成员的类型的可访问性。Normally, the accessibility of a member is not greater than the accessibility of the type that contains it. 但是,如果内部类的公共成员实现了接口方法或替代了在公共基类中定义的虚拟方法,则可从该程序集的外部访问该成员。However, a public member of an internal class might be accessible from outside the assembly if the member implements interface methods or overrides virtual methods that are defined in a public base class.

为字段、属性或事件的任何成员的类型必须至少与该成员本身具有相同的可访问性。The type of any member that is a field, property, or event must be at least as accessible as the member itself. 同样,为方法、索引器或委托的任何成员的返回类型和参数类型必须至少与该成员本身具有相同的可访问性。Similarly, the return type and the parameter types of any member that is a method, indexer, or delegate must be at least as accessible as the member itself. 例如,不能具有返回类 C 的公共方法 M,除非 C 也是公共的。For example, you cannot have a public method M that returns a class C unless C is also public. 同样,如果 A 声明为私有,则不能具有类型 A 的受保护的属性。Likewise, you cannot have a protected property of type A if A is declared as private.

用户定义的运算符始终必须声明为公共和静态。User-defined operators must always be declared as public and static. 有关详细信息,请参阅运算符重载For more information, see Operator overloading.

终结器不能具有可访问性修饰符。Finalizers cannot have accessibility modifiers.

若要设置类或结构成员的访问级别,向成员声明添加适当的关键字,如以下示例中所示。To set the access level for a class or struct member, add the appropriate keyword to the member declaration, as shown in the following example.

// 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; }
    }
}

备注

受保护的内部可访问性级别意味着受保护或内部,而非受保护和内部。The protected internal accessibility level means protected OR internal, not protected AND internal. 换而言之,可以从同一程序集中的任何类(包括派生类)访问受保护的内部成员。In other words, a protected internal member can be accessed from any class in the same assembly, including derived classes. 若要将同一程序集中的可访问性限制为仅派生类,请声明类本身为内部,并声明其成员为受保护。To limit accessibility to only derived classes in the same assembly, declare the class itself internal, and declare its members as protected. 此外,从 C# 7.2 开始,可以使用专用受保护的访问修饰符实现相同的效果,而无需使包含的类属于内部。Also, starting with C# 7.2, you can use the private protected access modifier to achieve the same result without need to make the containing class internal.

其他类型Other Types

在命名空间内直接声明的接口可以声明为公共或内部,就像类和结构一样,接口默认设置为内部访问。Interfaces declared directly within a namespace can be declared as public or internal and, just like classes and structs, interfaces default to internal access. 接口成员始终为公共的,因为接口的用途是启用其他类型以访问类或结构。Interface members are always public because the purpose of an interface is to enable other types to access a class or struct. 没有访问修饰符可以应用于接口成员。No access modifiers can be applied to interface members.

枚举成员始终为公共的,并且不应用任何访问修饰符。Enumeration members are always public, and no access modifiers can be applied.

委托类似于类和结构。Delegates behave like classes and structs. 默认情况下,当在命名空间内直接声明它们时,它们具有内部访问,当将它们嵌套在命名空间内时,它们具有私有访问。By default, they have internal access when declared directly within a namespace, and private access when nested.

C# 语言规范C# Language Specification

有关详细信息,请参阅 C# 语言规范For more information, see the C# Language Specification. 该语言规范是 C# 语法和用法的权威资料。The language specification is the definitive source for C# syntax and usage.

请参阅See also