类,方法,成员,构造函数,委托和接口的默认访问修饰符是什么?
类,方法,成员,构造函数,委托和接口的默认访问修饰符是什么?
Answers:
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节):
根据成员声明发生的上下文,仅允许某些类型的声明的可访问性。此外,当成员声明不包含任何访问修饰符时,声明发生的上下文将确定默认的声明可访问性。
- 命名空间隐式具有公共声明的可访问性。名称空间声明中不允许使用访问修饰符。
- 在编译单元或命名空间中声明的类型可以具有公共或内部声明的可访问性,并且默认为内部声明的可访问性。
- 类成员可以具有五种声明的可访问性中的任何一种,并且默认为私有声明的可访问性。(请注意,声明为类成员的类型可以具有五种声明的可访问性中的任何一种,而声明为名称空间成员的类型可以仅具有公共或内部声明的可访问性。)
- Struct成员可以具有public,internal或private声明的可访问性,并且默认为private声明的可访问性,因为结构是隐式密封的。在结构中引入的Struct成员(即不被该结构继承)不能具有受保护的或受保护的内部声明的可访问性。(请注意,声明为结构成员的类型可以具有公共,内部或私有声明的可访问性,而声明为命名空间成员的类型只能具有公共或内部声明的可访问性。)
- 接口成员隐式具有公共声明的可访问性。接口成员声明上不允许使用访问修饰符。
- 枚举成员隐式具有公开声明的可访问性。枚举成员声明中不允许使用访问修饰符。
(请注意,嵌套类型将位于“类成员”或“结构成员”部分下,因此默认为私有可见性。)
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!
class Foo : IFoo { IFoo.M() {} } ... Foo a = new Foo();
您不能访问M
有a.M()
,但你可以访问它(a as IFoo).M()
。(有关详细信息,请查看规格)
简短答案:最小的访问权限(请参阅Jon Skeet的答案)。
长答案:
非嵌套类型,枚举和委托可访问性(只能具有内部或公共可访问性)
| Default | Permitted declared accessibilities ------------------------------------------------------------------ namespace | public | none (always implicitly public) enum | public | none (always implicitly public) 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 | none (always implicitly public) interface | public | none class | private | All¹ struct | private | public, internal, private² delegate | private | All¹ constructor | private | All¹ interface member | public | none (always implicitly public) method | private | All¹ field | private | All¹ user-defined operator| none | public (must be declared public)
¹全部===公共,受保护,内部,私有,受保护内部
²结构无法继承自结构或类(尽管它们可以继承接口),因此保护不是有效的修饰符
嵌套类型的可访问性取决于其可访问性域,该域由成员的声明的可访问性和紧靠其包含的类型的可访问性域确定。但是,嵌套类型的可访问性域不能超过包含类型的可访问性域。
注意:CIL还提供了受保护的和内部的保护(相对于现有的受保护的“或”内部保护),但是据我所知,当前在C#中不可用。
看到:
http://msdn.microsoft.com/en-us/library/ba0a1yw2.aspx
http://msdn.microsoft.com/en-us/library/ms173121.aspx
http://msdn.microsoft.com/zh- us / library / cx03xt0t.aspx
(我喜欢Microsoft URI的人...)
类和结构可访问性
直接在名称空间中声明的类和结构(换句话说,未嵌套在其他类或结构中)可以是公共的或内部的。如果未指定访问修饰符,则“内部”为默认设置。
可以将结构成员(包括嵌套的类和结构)声明为public,internal或private。类成员,包括嵌套的类和结构,可以是公共的,受保护的内部,受保护的,内部的,私有的受保护的或私有的。默认情况下,类成员和结构成员(包括嵌套的类和结构)的访问级别是私有的。私有嵌套类型不能从包含类型的外部访问。
派生类不能比其基本类型具有更大的可访问性。换句话说,您不能拥有从内部类A派生的公共类B。如果允许这样做,则将具有使A公开的效果,因为可以从派生类访问A的所有受保护成员或内部成员。
您可以使用来使其他特定程序集访问您的内部类型
InternalsVisibleToAttribute
。有关更多信息,请参见朋友装配。类和结构成员的可访问性
可以使用六种访问类型中的任何一种来声明类成员(包括嵌套的类和结构)。无法将结构成员声明为受保护的,因为结构不支持继承。
通常,成员的可访问性不大于包含该成员的类型的可访问性。但是,如果内部类的公共成员实现接口方法或覆盖公共基类中定义的虚拟方法,则可以从程序集外部访问该内部成员。
作为字段,属性或事件的任何成员的类型必须至少具有与成员本身一样的可访问性。同样,作为方法,索引器或委托的任何成员的返回类型和参数类型必须至少与成员本身具有相同的可访问性。例如,除非C也是公共的,否则您不能具有返回类C的公共方法M。同样,如果将A声明为私有,则不能拥有类型A的受保护属性。
用户定义的运算符必须始终声明为public和static。有关更多信息,请参见运算符重载。
终结器不能具有辅助功能修改器。
其他种类
可以在名称空间中直接声明的接口可以声明为公共或内部,并且与类和结构一样,接口默认为内部访问。接口成员始终是公共的,因为接口的目的是使其他类型能够访问类或结构。不能将访问修饰符应用于接口成员。
枚举成员始终是公共的,并且不能应用访问修饰符。
代表的行为类似于类和结构。默认情况下,当直接在名称空间中声明时,它们具有内部访问权,而在嵌套时具有私有访问权。
最简单的答案如下:
默认情况下,C#中的所有成员始终都使用LEAST可访问修饰符。
这就是为什么程序集中的所有顶级类默认情况下都是“内部”的原因,这意味着它们对于所在的程序集是公共的,但对私有程序集是私有的,或者被排除在对外部程序集的访问之外。顶级课程的唯一其他选择是公开,这更易于访问。对于嵌套类型,除少数罕见例外(例如枚举的成员和只能公开的接口)外,它都是私有的。一些例子。对于顶级类和接口,默认值为:
类动物与内部类动物相同
界面动物与公共界面动物相同
对于嵌套的类和接口(内部类型),默认值为:
类动物与私人类动物相同
接口动物与专用接口动物相同
如果仅假设默认值始终是最私有的,则无需使用访问器,直到需要更改默认值。简单。