C#中的默认访问修饰符是什么?

Sur*_*har 355 c# access-modifiers

类,方法,成员,构造函数,委托和接口的默认访问修饰符是什么?

Jon*_*eet 454

C#中所有内容的默认访问权限是"您可以为该成员声明的最受限制的访问权限".

例如:

namespace MyCompany
{
    class Outer
    {
        void Foo() {}
        class Inner {}
    }
}
Run Code Online (Sandbox Code Playgroud)

相当于

namespace MyCompany
{
    internal class Outer
    {
        private void Foo() {}
        private class Inner {}
    }
}
Run Code Online (Sandbox Code Playgroud)

对此的一种例外是使属性(通常是setter)的一部分比属性本身的声明可访问性更受限制:

public string Name
{
    get { ... }
    private set { ... } // This isn't the default, have to do it explicitly
}
Run Code Online (Sandbox Code Playgroud)

这就是C#3.0规范所说的内容(第3.5.1节):

根据成员声明发生的上下文,仅允许某些类型的已声明可访问性.此外,当成员声明不包含任何访问修饰符时,发生声明的上下文确定默认声明的可访问性.

  • 命名空间隐式具有公共声明的可访问性.命名空间声明中不允许访问修饰符.
  • 在编译单元或名称空间中声明的类型可以具有公共或内部声明的可访问性,并且默认为内部声明的可访问性.
  • 类成员可以具有五种声明的可访问性中的任何一种,并且默认为私有声明的可访问性.(请注意,声明为类成员的类型可以具有任何五种声明的可访问性,而声明为命名空间成员的类型只能具有公共或内部声明的可访问性.)
  • 结构成员可以具有公共,内部或私有声明的可访问性,并且默认为私有声明的可访问性,因为结构是隐式密封的.在结构中引入的struct成员(即,不由该结构继承)不能具有受保护或受保护的内部声明的可访问性.(请注意,声明为结构成员的类型可以具有公共,内部或私有声明的可访问性,而声明为命名空间成员的类型只能具有公共或内部声明的可访问性.)
  • 接口成员隐式具有公共声明的可访问性.接口成员声明中不允许访问修饰符.
  • 枚举成员隐式具有公共声明的可访问性.枚举成员声明中不允许访问修饰符.

(请注意,嵌套类型将属于"类成员"或"结构成员"部分 - 因此默认为私有可见性.)

  • @ZaidMasud:不,不是.如果声明构造函数但未指定可访问性,则它将是私有的.请参阅C#规范的第10.3.5节. (19认同)
  • 如果默认是最受限制的访问,那么为什么类的默认值不是私有的?啊,因为:"......声明为命名空间成员的类型只能具有公共或内部声明的可访问性." (5认同)
  • 你答案中的第一行直接记录了所有内容.我只是喜欢它:-)现在我不必为什么是关于类或结构或成员或函数的默认访问说明符情况.非常感谢. (4认同)
  • 注意:在 C# 8 中,接口中允许使用访问修饰符,并且默认为 public。 (2认同)

Joh*_*nan 148

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!
Run Code Online (Sandbox Code Playgroud)

  • 这并不清楚如果一个类也是一个成员(由于是一个嵌套类型),那么它默认为private.此外,接口和枚举的成员始终是公共的. (12认同)

Ben*_*Ben 124

简短回答:最小可能访问(参见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
Run Code Online (Sandbox Code Playgroud)

嵌套类型和成员可访问性

                     | 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)
Run Code Online (Sandbox Code Playgroud)

¹全部=== public,protected,internal,private,protected internal

²结构体不能从结构或类继承(尽管它们可以,接口),因此受保护的不是有效的修饰符

嵌套类型的可访问性取决于其可访问性域,该域由成员的已声明可访问性和直接包含类型的可访问性域确定.但是,嵌套类型的可访问性域不能超过包含类型的可访问性域.

注意: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
(我喜欢Microsoft URIs的人...)


Adr*_*der 11

看看Access Modifiers(C#编程指南)


如果未指定访问修饰符,则Class和Struct Accessibility Internal是默认值.

类和结构成员可访问性
类成员(包括嵌套类和结构)可以使用五种访问类型中的任何一种进行声明.不能将Struct成员声明为protected,因为struct不支持继承.

成员的可访问性永远不会大于其包含类型的可访问性

用户定义的运算符必须始终声明为public.有关更多信息,请参阅operator(C#参考).

析构函数不能具有可访问性修饰符.

其他类型
直接使用命名空间声明的接口可以声明为public或internal,类似于类和结构,接口默认为内部访问.

枚举成员始终是公共的,并且不能应用任何访问修饰符.

默认情况下,代理具有内部访问权限.

  • 令我惊讶的是,尽管不正确(指出了那些不准确之处),但这个答案继续得到提升 - 即使这种不准确性来自MS.这很容易验证:创建一个具有默认辅助功能的嵌套类,并使用反射器进行检查.它将是私人的,而不是像这里声称的内部. (9认同)
  • 这一点让我担心:"成员的可访问性永远不会超过其包含类型的可访问性" - 考虑`内部类Foo:IDisposable {public void Dispose(){}}`.此外,"默认情况下,委托具有内部访问权限"是不正确的 - 如果它们在一个类型中声明,它们将是私有的.同样,如果没有指定访问修饰符,则"内部是默认值"仅适用于顶级类型. (6认同)

Cha*_*Zoo 11

默认情况下,类是内部的。

  • 默认情况下,类成员是私有的。

接口默认为内部

  • 默认情况下,接口成员是公共的。(接口不允许我们为其成员指定任何类型的可访问性。)

    注意:如果您尝试为接口成员指定任何访问说明符,则会显示编译错误。

结构默认为内部

  • 默认情况下,结构成员是私有的。


Asi*_*taq 7

我想添加一些文档链接。在此处查看更多详细信息

在此处输入图片说明

  • 类默认是内部的而不是私有的。 (3认同)

Sto*_*ely 6

最简单的答案如下......

默认情况下,C# 中的所有成员始终采用可能的 LEAST 可访问修饰符。

这就是为什么默认情况下程序集中的所有顶级类都是“内部”的,这意味着它们对其所在的程序集是公共的,但对外部程序集是私有的或被排除在外。顶级类的唯一其他选择是公共的,它更容易访问。对于嵌套类型,除了一些罕见的例外(例如只能是公共的枚举和接口的成员)之外,它都是私有的。一些例子。

C# 中有两类访问修饰符

顶层...

class MyClass {
    ...
}
Run Code Online (Sandbox Code Playgroud)

...以及会员级别(在另一个班级内等)

class MyClass {
    class MySubClass {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

每个都有自己不同的默认值。一般来说,所有顶级都可以是internal(默认,与没有访问修饰符相同,并阻止外部程序集访问)或public(对程序集和外部程序集访问开放)。

顶级类型访问修饰符

对于顶级类、结构、接口等,默认值都是internaldefault,如使用“animal”类作为示例所示。这意味着它们默认对外部程序集访问关闭:

Animal{} 类与Animal{} 类相同internal

接口 Animal{}与接口 Animal{}相同internal

会员级别类型访问修饰符

对于嵌套类和接口(内部类型),默认值通常是private除了接口和枚举之外的public。这通常意味着类中的成员被排除在内部程序集及其内部程序集外部程序集对类成员的外部访问之外:

Animal{} 类与Animal{} 类相同private

接口 Animal{}与接口 Animal{}相同public

了解您的顶级类型还控制其中的成员。因此,如果将顶级访问修饰符internalto更改public,类内的任何公共成员或受保护的派生成员都可以突然被外部程序集访问!

请记住,当从控制可访问性的基类派生时,这些规则也可能被打破。但是,如果您只是假设 C# 类型的默认值始终是最私有的,那么在需要更改默认值之前,您不需要使用自定义访问修饰符。它们开箱即用,非常安全!