类、方法、成员、构造函数、委托和接口的默认访问修饰符是什么?
9 回答
C# 中所有内容的默认访问权限是“您可以为该成员声明的最受限制的访问权限”。
例如:
namespace MyCompany
{
class Outer
{
void Foo() {}
class Inner {}
}
}
相当于
namespace MyCompany
{
internal class Outer
{
private void Foo() {}
private class Inner {}
}
}
一种例外是使属性的一部分(通常是 setter)比属性本身声明的可访问性更受限制:
public string Name
{
get { ... }
private set { ... } // This isn't the default, have to do it explicitly
}
这就是 C# 3.0 规范必须说的(第 3.5.1 节):
根据成员声明发生的上下文,仅允许某些类型的声明可访问性。此外,当成员声明不包含任何访问修饰符时,发生声明的上下文决定了默认声明的可访问性。
- 命名空间隐含地具有公开声明的可访问性。命名空间声明中不允许使用访问修饰符。
- 在编译单元或命名空间中声明的类型可以具有公共或内部声明的可访问性,并且默认为内部声明的可访问性。
- 类成员可以具有五种声明的可访问性中的任何一种,并且默认为私有声明的可访问性。(请注意,声明为类成员的类型可以具有五种声明的可访问性中的任何一种,而声明为命名空间成员的类型只能具有公共或内部声明的可访问性。)
- 结构成员可以具有公共、内部或私有声明的可访问性,并且默认为私有声明的可访问性,因为结构是隐式密封的。在结构中引入的结构成员(即不被该结构继承)不能具有受保护或受保护的内部声明的可访问性。(请注意,声明为结构成员的类型可以具有公共、内部或私有声明的可访问性,而声明为命名空间成员的类型只能具有公共或内部声明的可访问性。)
- 接口成员隐式地具有公开声明的可访问性。接口成员声明中不允许使用访问修饰符。
- 枚举成员隐含地具有公开声明的可访问性。枚举成员声明中不允许使用访问修饰符。
(请注意,嵌套类型将属于“类成员”或“结构成员”部分 - 因此默认为私有可见性。)
top level class: internal
method: private
members (unless an interface or enum): private (including nested classes)
members (of interface or enum): public
constructor: private (note that if no constructor is explicitly defined, a public default constructor will be automatically defined)
delegate: internal
interface: internal
explicitly implemented interface member: public!
简短回答:尽可能少的访问(参见 Jon Skeet 的回答)。
长答案:
非嵌套类型、枚举和委托可访问性(可能只有内部或公共可访问性)
| Default | Permitted declared accessibilities ------------------------------------------------------------------ namespace | public | none (always implicitly public) enum | public | public, internal interface | internal | public, internal class | internal | public, internal struct | internal | public, internal delegate | internal | public, internal
嵌套类型和成员可访问性
| Default | Permitted declared accessibilities ------------------------------------------------------------------ namespace | public | none (always implicitly public) enum | public | All¹ interface | public | All¹ class | private | All¹ struct | private | public, internal, private² delegate | private | All¹ constructor | private | All¹ enum member | public | none (always implicitly public) interface member | public | none (always implicitly public) method | private | All¹ field | private | All¹ user-defined operator| none | public (must be declared public)
¹ 全部 === 公共、受保护、内部、私有、受保护内部
² 结构不能从结构或类继承(尽管它们可以,接口),因此 protected 不是有效的修饰符
嵌套类型的可访问性取决于其可访问域,该域由成员声明的可访问性和直接包含类型的可访问域共同决定。但是,嵌套类型的可访问域不能超过包含类型的可访问域。
注意:CIL 还提供了受保护的和内部的(与现有的受保护的“或”内部相反),但据我所知,这目前不适用于 C#。
看:
http://msdn.microsoft.com/en-us/library/ba0a1yw2.aspx
http://msdn.microsoft.com/en-us/library/ms173121.aspx
http://msdn.microsoft.com/en- us/library/cx03xt0t.aspx
(我喜欢微软的 URLs...)
类和结构可访问性
直接在命名空间中声明的类和结构(换句话说,不嵌套在其他类或结构中)可以是公共的或内部的。如果未指定访问修饰符,则默认为 Internal。
结构成员,包括嵌套类和结构,可以声明为公共、内部或私有。类成员,包括嵌套类和结构,可以是公共的、受保护的内部的、受保护的、内部的、私有的、受保护的或私有的。默认情况下,类成员和结构成员(包括嵌套类和结构)的访问级别是私有的。不能从包含类型外部访问私有嵌套类型。
派生类不能比它们的基类型具有更大的可访问性。换句话说,您不能拥有从内部类 A 派生的公共类 B。如果允许这样做,则会产生使 A 成为公共的效果,因为 A 的所有受保护或内部成员都可以从派生类访问。
您可以使用
InternalsVisibleToAttribute
. 有关详细信息,请参阅友元程序集。类和结构成员可访问性
可以使用六种访问类型中的任何一种来声明类成员(包括嵌套类和结构)。结构成员不能声明为受保护的,因为结构不支持继承。
通常,成员的可访问性不大于包含它的类型的可访问性。但是,如果成员实现接口方法或覆盖在公共基类中定义的虚拟方法,则可以从程序集外部访问内部类的公共成员。
作为字段、属性或事件的任何成员的类型必须至少与成员本身一样可访问。同样,作为方法、索引器或委托的任何成员的返回类型和参数类型必须至少与成员本身一样可访问。例如,您不能有一个返回类 C 的公共方法 M,除非 C 也是公共的。同样,如果 A 被声明为私有,则不能拥有 A 类型的受保护属性。
用户定义的运算符必须始终声明为 public 和 static。有关详细信息,请参阅运算符重载。
终结器不能有可访问性修饰符。
其他类型
直接在命名空间中声明的接口可以声明为公共的或内部的,就像类和结构一样,接口默认为内部访问。接口成员始终是公共的,因为接口的目的是使其他类型能够访问类或结构。不能将访问修饰符应用于接口成员。
枚举成员始终是公共的,并且不能应用访问修饰符。
委托的行为类似于类和结构。默认情况下,它们在命名空间中直接声明时具有内部访问权限,而嵌套时则具有私有访问权限。
类默认为内部。
- 默认情况下,类成员是私有的。
接口默认为内部。
默认情况下,接口成员是公共的。(接口不允许我们为其成员指定任何类型的可访问性。)
注意:如果您尝试为接口的成员指定任何访问说明符,则会显示编译错误。
结构默认为内部。
- 结构成员默认是私有的。
我想添加一些文档链接。在此处查看更多详细信息。
最简单的答案如下......
默认情况下,C# 中的所有成员始终采用 LEAST 可访问修饰符。
这就是为什么程序集中的所有顶级类默认情况下都是“内部的”,这意味着它们对于它们所在的程序集是公共的,但私有的或被排除在对外部程序集的访问之外。顶级课程的唯一其他选择是更易于访问的公共。对于嵌套类型,它都是私有的,除了一些罕见的例外,比如只能是公共的枚举成员和接口。一些例子。对于顶级类和接口,默认值为:
类 Animal与内部类Animal相同
接口Animal与公共接口Animal相同
对于嵌套类和接口(内部类型),默认值为:
类 Animal与私有类Animal相同
接口Animal与私有接口Animal相同
如果您只是假设默认值始终是最私密的,那么您不需要使用访问器,直到您需要更改默认值。简单的。
命名空间级别:internal
类型级别:private
内部是默认修饰符