Каковы модификаторы доступа по умолчанию в C#?

Что такое модификатор доступа по умолчанию для классов, методов, членов, конструкторов, делегатов и интерфейсов?

10 ответов

Решение

Доступ по умолчанию для всего в C# - "самый ограниченный доступ, который вы можете объявить для этого члена".

Так, например:

namespace MyCompany
{
    class Outer
    {
        void Foo() {}
        class Inner {}
    }
}

эквивалентно

namespace MyCompany
{
    internal class Outer
    {
        private void Foo() {}
        private class Inner {}
    }
}

Единственное исключение из этого делает одну часть свойства (обычно установщик) более ограниченной, чем объявленная доступность самого свойства:

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!

Краткий ответ: минимально возможный доступ (см. Ответ Джона Скита).

Длинный ответ:

Не вложенные типы, перечислимые и делегированные права доступа (могут иметь только внутреннюю или общедоступную доступность)

                     | 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/en-us/library/cx03xt0t.aspx
(Человек, я люблю Microsoft URIs...)

Класс является внутренним по умолчанию.

  • Члены класса по умолчанию закрыты.

Интерфейс является внутренним по умолчанию.

  • Члены интерфейса являются общедоступными по умолчанию. (Интерфейсы не позволяют нам указывать какой-либо доступ к его членам.)

    Примечание. Если вы попытаетесь указать какой-либо спецификатор доступа для членов интерфейса, это приведет к ошибке компиляции.

Struct является внутренним по умолчанию.

  • Члены структуры по умолчанию являются закрытыми.

Посмотрите на Модификаторы доступа (Руководство по программированию в C#)

Доступность классов и структур
Внутренний является значением по умолчанию, если не указан модификатор доступа.

Доступность членов класса и структуры
Члены класса (включая вложенные классы и структуры) могут быть объявлены с любым из пяти типов доступа. Члены структуры не могут быть объявлены защищенными, потому что структуры не поддерживают наследование.

Доступность члена никогда не может быть больше, чем доступность его содержащего типа.

Пользовательские операторы всегда должны быть объявлены как публичные. Для получения дополнительной информации см. Оператор (C# Reference).

Деструкторы не могут иметь модификаторы доступности.

Другие типы
Интерфейсы, объявленные непосредственно с пространством имен, могут быть объявлены как публичные или внутренние и как классы и структуры, интерфейсы по умолчанию для внутреннего доступа.

Члены перечисления всегда общедоступны, и модификаторы доступа не могут быть применены.

По умолчанию делегаты имеют внутренний доступ.

Я хотел бы добавить ссылку на документацию. Проверьте более подробно здесь.

Самый простой ответ заключается в следующем.....

Все члены в C# всегда используют наименьший доступный модификатор, возможный по умолчанию.

Вот почему все классы верхнего уровня в сборке по умолчанию являются "внутренними", что означает, что они являются общедоступными для сборки, в которой они находятся, но являются закрытыми или исключены из доступа к внешним сборкам. Единственный другой вариант для класса верхнего уровня - публичный, который более доступен. Для вложенных типов все это закрыто, за исключением нескольких редких исключений, таких как члены перечислений и интерфейсов, которые могут быть только публичными. Некоторые примеры. В случае классов и интерфейсов верхнего уровня значения по умолчанию:

класс Animal такой же как внутренний класс Animal

Интерфейс Animal такой же, как открытый интерфейс Animal

В случае вложенных классов и интерфейсов (внутри типов) значения по умолчанию:

Класс Animal такой же, как у частного класса Animal

Интерфейс Animal такой же, как и у частного интерфейса Animal

Если вы просто предполагаете, что значение по умолчанию всегда является самым закрытым, вам не нужно использовать средства доступа, пока вам не нужно изменить значение по умолчанию. Легко.

Уровень пространства имен: internal

Тип уровня: private

Внутренний является модификатором по умолчанию

internalмодификатор доступа по умолчанию для класса.

privateмодификатор доступа по умолчанию для членов класса.

Другие вопросы по тегам