Каков модификатор доступа по умолчанию для классов, методов, членов, конструкторов, делегатов и интерфейсов?
Каков модификатор доступа по умолчанию для классов, методов, членов, конструкторов, делегатов и интерфейсов?
Ответы:
Доступ по умолчанию для всего в 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!
class Foo : IFoo { IFoo.M() {} } ... Foo a = new Foo();
вы не можете доступа M
с a.M()
, однако вы можете получить к нему доступ (a as IFoo).M()
. (Проверьте спецификацию для получения дополнительной информации о специфике)
Краткий ответ: минимально возможный доступ (см. Ответ Джона Скита).
Длинный ответ:
Не вложенные типы, перечислимые и делегированные права доступа ( могут иметь только внутреннюю или общедоступную доступность )
| 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 ...)
Посмотрите на Модификаторы доступа (Руководство по программированию в C #)
Доступность класса и структуры
Классы и структуры, которые объявлены непосредственно в пространстве имен (другими словами, которые не вложены в другие классы или структуры), могут быть открытыми или внутренними. Внутренний является значением по умолчанию, если не указан модификатор доступа.
Члены структуры, включая вложенные классы и структуры, могут быть объявлены как публичные, внутренние или частные. Члены класса, включая вложенные классы и структуры, могут быть публичными, защищенными внутренними, защищенными, внутренними, частными защищенными или частными. Уровень доступа для членов класса и членов структуры, включая вложенные классы и структуры, по умолчанию является закрытым. Закрытые вложенные типы недоступны извне содержащего типа.
Производные классы не могут иметь большей доступности, чем их базовые типы. Другими словами, у вас не может быть общедоступного класса B, производного от внутреннего класса A. Если бы это было разрешено, это сделало бы действие A общедоступным, поскольку все защищенные или внутренние члены A доступны из производного класса.
Вы можете включить определенные другие сборки для доступа к вашим внутренним типам с помощью
InternalsVisibleToAttribute
. Для получения дополнительной информации см. Сборки друзей.Доступность членов класса и структуры
Члены класса (включая вложенные классы и структуры) могут быть объявлены с любым из шести типов доступа. Члены структуры не могут быть объявлены защищенными, поскольку структуры не поддерживают наследование.
Обычно доступность члена не превышает доступность типа, который его содержит. Однако открытый член внутреннего класса может быть доступен извне сборки, если он реализует методы интерфейса или переопределяет виртуальные методы, определенные в общедоступном базовом классе.
Тип любого члена, являющегося полем, свойством или событием, должен быть как минимум таким же доступным, как и сам член. Аналогично, тип возвращаемого значения и типы параметров любого члена, являющегося методом, индексатором или делегатом, должны быть как минимум такими же доступными, как и сам член. Например, вы не можете иметь открытый метод M, который возвращает класс C, если C также не является открытым. Аналогично, вы не можете иметь защищенное свойство типа A, если A объявлено как личное.
Определяемые пользователем операторы всегда должны быть объявлены как public и static. Для получения дополнительной информации см. Перегрузка оператора.
Финализаторы не могут иметь модификаторы доступности.
Другие типы
Интерфейсы, объявленные непосредственно в пространстве имен, могут быть объявлены как публичные или внутренние, и, как и классы и структуры, интерфейсы по умолчанию имеют внутренний доступ. Члены интерфейса всегда общедоступны, потому что цель интерфейса - предоставить другим типам доступ к классу или структуре. Модификаторы доступа не могут быть применены к элементам интерфейса.
Члены перечисления всегда общедоступны, и модификаторы доступа не могут быть применены.
Делегаты ведут себя как классы и структуры. По умолчанию они имеют внутренний доступ при объявлении непосредственно в пространстве имен и закрытый доступ при вложении.
Класс является внутренним по умолчанию.
Интерфейс является внутренним по умолчанию.
Члены интерфейса являются общедоступными по умолчанию. (Интерфейсы не позволяют нам указывать какой-либо доступ к его членам.)
Примечание. Если вы попытаетесь указать какой-либо спецификатор доступа к членам интерфейса, это приведет к ошибке компиляции.
Struct является внутренним по умолчанию.
Я хотел бы добавить ссылку на документацию. Проверьте более подробно здесь .
Самый простой ответ заключается в следующем .....
Все члены в C # всегда используют наименьший доступный модификатор, возможный по умолчанию.
Вот почему все классы верхнего уровня в сборке по умолчанию являются «внутренними», что означает, что они являются общедоступными для сборки, в которой они находятся, но являются закрытыми или исключены из доступа к внешним сборкам. Единственный другой вариант для класса верхнего уровня - публичный, который более доступен. Для вложенных типов все это закрыто, за исключением нескольких редких исключений, таких как члены перечислений и интерфейсов, которые могут быть только публичными. Некоторые примеры. В случае классов и интерфейсов верхнего уровня значения по умолчанию:
класс Animal такой же как внутренний класс Animal
Интерфейс Animal такой же, как открытый интерфейс Animal
В случае вложенных классов и интерфейсов (внутри типов) значения по умолчанию:
Класс Animal такой же, как у частного класса Animal
Интерфейс Animal такой же, как частный интерфейс Animal
Если вы просто предполагаете, что значение по умолчанию всегда является самым закрытым, вам не нужно использовать средства доступа, пока вам не нужно изменить значение по умолчанию. Легко.