Які модифікатори доступу за замовчуванням в C #?


383

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

Відповіді:


485

Доступ за замовчуванням до всього в 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
Це не дає зрозуміти, що якщо клас також є членом (через те, що є вкладеним типом), то він за замовчуванням є приватним. Також учасники інтерфейсу та enum завжди публічні.
Джон Скіт

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
(Man I love Microsoft URI ...)


12

Перегляньте Модифікатори доступу (Посібник з програмування C #)

Доступність для класу та структури

Класи та структури, які оголошуються безпосередньо в просторі імен (іншими словами, які не вкладені в інші класи чи структури), можуть бути публічними або внутрішніми. Внутрішнє - це за замовчуванням, якщо не вказаний модифікатор доступу.

Члени структури, включаючи вкладені класи та структури, можуть бути оголошені як громадські, внутрішні чи приватні. Учасники класу, включаючи вкладені класи та структури, можуть бути загальнодоступними, захищеними внутрішніми, захищеними, внутрішніми, приватними, захищеними або приватними. Рівень доступу для членів класу та членів структури, включаючи вкладені класи та структури, за замовчуванням є приватним. Приватні вкладені типи недоступні ззовні, що містять тип.

Отримані класи не можуть мати більшу доступність, ніж їх базові типи. Іншими словами, у вас не може бути публічного класу B, який походить від внутрішнього класу A. Якщо це було дозволено, це призвело б до публічного оприлюднення, оскільки всі захищені або внутрішні члени A доступні з похідного класу.

Ви можете дозволити певним іншим збіркам отримати доступ до внутрішніх типів за допомогою InternalsVisibleToAttribute. Для отримання додаткової інформації див. Дружні збори.

Доступність для класу та структури

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

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

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

Оператори, визначені користувачем, завжди повинні бути оголошені загальнодоступними та статичними. Для отримання додаткової інформації див. Перевантаження оператора.

Фіналізатори не можуть мати модифікаторів доступності.

Інші типи

Інтерфейси, оголошені безпосередньо в просторі імен, можуть бути оголошені загальнодоступними або внутрішніми, як і класи та структури, інтерфейси за замовчуванням для внутрішнього доступу. Учасники інтерфейсу завжди є загальнодоступними, оскільки мета інтерфейсу - дозволити іншим типам доступу до класу чи структури. До членів інтерфейсу не можна застосовувати модифікаторів доступу.

Учасники переліку завжди є загальнодоступними, і не можна застосовувати модифікатори доступу.

Делегати поводяться як класи та структури. За замовчуванням вони мають внутрішній доступ при оголошенні безпосередньо в просторі імен та приватний доступ, коли вони вкладені.


8

Клас за замовчуванням внутрішній .

  • Учасники класу за замовчуванням приватні .

Інтерфейс за замовчуванням внутрішній .

  • Учасники інтерфейсу за замовчуванням є загальнодоступними . (Інтерфейси не дозволяють нам визначати будь-який вид доступності для його членів.)

    Примітка. Якщо ви спробуєте вказати будь-який специфікатор доступу для членів інтерфейсу, то він показує помилку компіляції.

За замовчуванням структура є внутрішньою .

  • Учасники структури за замовчуванням приватні .

5

Я хотів би додати посилання на документацію. Перегляньте детальніше тут .

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


1
Клас за замовчуванням внутрішній, а не приватний.
Баахубалі

1
Де я писав, що приватний клас?
Асиф Муштак

Ця таблиця дійсна лише для вкладених типів.
BlueSilver

клас є внутрішнім за замовчуванням, а клас всередині простору імен не може бути приватним. але клас всередині класу (вкладений клас) може бути приватним
Арун

Модифікатор доступу до інтерфейсу за замовчуванням є внутрішнім .
Камала Ганчінал

4

Найпростіша відповідь:

Усі члени C # завжди приймають ЗАМОВНИЙ доступний модифікатор за замовчуванням.

Ось чому всі класи вищого рівня в зборах є "внутрішніми" за замовчуванням, це означає, що вони є загальнодоступними для зборів, в яких вони перебувають, але приватними або виключаються з доступу до зовнішніх зборів. Єдиний інший варіант для класу вищого рівня - це публічний доступ, який є більш доступним. Для вкладених типів це все приватне, за винятком кількох рідкісних винятків, таких як члени переліків та інтерфейсів, які можуть бути лише загальнодоступними. Деякі приклади. Що стосується класів та інтерфейсів вищого рівня, типовими параметрами є:

клас Тварина те саме, що і внутрішній клас Тварина

інтерфейс Animal такий же, як і публічний інтерфейс Animal

Що стосується вкладених класів та інтерфейсів (внутрішніх типів), типовими є:

клас Тварина те саме, що приватний клас тварини

інтерфейс Animal такий же, як приватний інтерфейс Animal

Якщо ви просто припускаєте, що за замовчуванням завжди є найбільш приватним, то вам не потрібно використовувати аксесуари, поки вам не потрібно буде змінити типовий. Легко.



Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.