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

384

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

Сурья Сасидхар
источник

Ответы:

486

Доступ по умолчанию для всего в 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):

В зависимости от контекста, в котором происходит объявление члена, разрешены только определенные типы объявленной доступности. Кроме того, когда объявление члена не включает никаких модификаторов доступа, контекст, в котором происходит объявление, определяет объявленную доступность по умолчанию.

  • Пространства имен неявно имеют публичную объявленную доступность. В объявлениях пространства имен запрещены модификаторы доступа.
  • Типы, объявленные в единицах компиляции или пространствах имен, могут иметь открытую или внутреннюю объявленную доступность и по умолчанию имеют внутреннюю объявленную доступность.
  • Члены класса могут иметь любой из пяти видов объявленной доступности и по умолчанию имеют закрытую объявленную доступность. (Обратите внимание, что тип, объявленный как член класса, может иметь любой из пяти видов объявленной доступности, тогда как тип, объявленный как член пространства имен, может иметь только открытую или внутреннюю объявленную доступность.)
  • Члены структуры могут иметь объявленную общедоступную, внутреннюю или частную объявленную доступность и по умолчанию имеют объявленную доступность частной, поскольку структуры неявно закрыты. Члены структуры, представленные в структуре (то есть не наследуемые этой структурой) не могут иметь защищенную или защищенную внутреннюю объявленную доступность. (Обратите внимание, что тип, объявленный как член структуры, может иметь открытую, внутреннюю или закрытую объявленную доступность, тогда как тип, объявленный как член пространства имен, может иметь только открытую или внутреннюю объявленную доступность.)
  • Члены интерфейса неявно имеют общедоступную объявленную доступность. В объявлениях членов интерфейса запрещены модификаторы доступа.
  • Члены перечисления неявно имеют публично объявленную доступность. В объявлениях членов перечисления запрещены модификаторы доступа.

(Обратите внимание, что вложенные типы подпадают под части «члены класса» или «члены структуры» - и поэтому по умолчанию имеют закрытую видимость.)

Джон Скит
источник
154
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!
Джон Бьюкенен
источник
13
Это не дает понять, что если класс также является членом (из-за того, что является вложенным типом), то по умолчанию он является закрытым. Кроме того, члены интерфейса и перечисления всегда общедоступны.
Джон Скит
1
@niry Нет, это не личное. Это публично. Он просто не получает слот в реализующего типа, так что если class Foo : IFoo { IFoo.M() {} } ... Foo a = new Foo();вы не можете доступа Mс a.M(), однако вы можете получить к нему доступ (a as IFoo).M(). (Проверьте спецификацию для получения дополнительной информации о специфике)
M.Stramm
130

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

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

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

                     | 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
(Человек, которого я люблю URI Microsoft ...)

Бен Астон
источник
12

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

Доступность класса и структуры

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

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

Производные классы не могут иметь большей доступности, чем их базовые типы. Другими словами, у вас не может быть общедоступного класса B, производного от внутреннего класса A. Если бы это было разрешено, это сделало бы действие A общедоступным, поскольку все защищенные или внутренние члены A доступны из производного класса.

Вы можете включить определенные другие сборки для доступа к вашим внутренним типам с помощью InternalsVisibleToAttribute. Для получения дополнительной информации см. Сборки друзей.

Доступность членов класса и структуры

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

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

Тип любого члена, являющегося полем, свойством или событием, должен быть как минимум таким же доступным, как и сам член. Аналогично, тип возвращаемого значения и типы параметров любого члена, являющегося методом, индексатором или делегатом, должны быть как минимум такими же доступными, как и сам член. Например, вы не можете иметь открытый метод M, который возвращает класс C, если C также не является открытым. Аналогично, вы не можете иметь защищенное свойство типа A, если A объявлено как личное.

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

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

Другие типы

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

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

Делегаты ведут себя как классы и структуры. По умолчанию они имеют внутренний доступ при объявлении непосредственно в пространстве имен и закрытый доступ при вложении.

Адриан Стандер
источник
8

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

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

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

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

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

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

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

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

введите описание изображения здесь

Асиф Муштак
источник
1
класс по умолчанию внутренний и не приватный.
Baahubali
1
Где я написал урок приватный?
Асиф Муштак
Эта таблица действительна только для вложенных типов.
BlueSilver
класс является внутренним по умолчанию, и класс внутри пространства имен не может быть закрытым. но класс внутри класса (вложенный класс) может быть закрытым
Арун
Модификатор доступа интерфейса - Внутренний по умолчанию.
Камала Ганчинал
4

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

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

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

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

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

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

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

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

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

Stokely
источник
1

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

renjucool
источник
0

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

Тип уровня: private

leppie
источник