Jakie są domyślne modyfikatory dostępu w C #?


Odpowiedzi:


485

Domyślny dostęp do wszystkiego w języku C # to „najbardziej ograniczony dostęp, jaki można zadeklarować dla tego członka” .

Na przykład:

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

jest równa

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

Jedynym rodzajem wyjątku jest ograniczenie jednej części właściwości (zwykle ustawiającej) niż deklarowana dostępność samej właściwości:

public string Name
{
    get { ... }
    private set { ... } // This isn't the default, have to do it explicitly
}

Oto, co mówi specyfikacja C # 3.0 (sekcja 3.5.1):

W zależności od kontekstu, w którym odbywa się deklaracja członka, dozwolone są tylko niektóre typy deklarowanej dostępności. Ponadto, gdy deklaracja członka nie zawiera żadnych modyfikatorów dostępu, kontekst, w którym deklaracja ma miejsce, określa domyślną deklarowaną dostępność.

  • Przestrzenie nazw domyślnie mają publicznie zadeklarowaną dostępność. Żadne modyfikatory dostępu nie są dozwolone w deklaracjach przestrzeni nazw.
  • Typy zadeklarowane w jednostkach kompilacji lub przestrzeniach nazw mogą mieć publiczną lub wewnętrzną deklarowaną dostępność i domyślnie wewnętrzną deklarowaną dostępność.
  • Członkowie klasy mogą mieć dowolny z pięciu rodzajów deklarowanej dostępności i domyślnie deklarowaną dostępność prywatną. (Należy zauważyć, że typ zadeklarowany jako członek klasy może mieć dowolny z pięciu rodzajów deklarowanej dostępności, podczas gdy typ zadeklarowany jako członek przestrzeni nazw może mieć tylko publiczną lub wewnętrzną deklarowaną dostępność).
  • Członkowie struktury mogą mieć publicznie, wewnętrznie lub prywatnie zadeklarowaną dostępność i domyślnie prywatną deklarowaną dostępność, ponieważ struktury są domyślnie zapieczętowane. Elementy struktury wprowadzone w strukturze (tj. Nie dziedziczone przez tę strukturę) nie mogą mieć zabezpieczonej ani chronionej wewnętrznej deklarowanej dostępności. (Należy zauważyć, że typ zadeklarowany jako członek struktury może mieć zadeklarowaną dostępność publiczną, wewnętrzną lub prywatną, podczas gdy typ zadeklarowany jako członek przestrzeni nazw może mieć tylko zadeklarowaną dostępność publiczną lub wewnętrzną).
  • Członkowie interfejsu domyślnie mają publicznie zadeklarowaną dostępność. Żadne modyfikatory dostępu nie są dozwolone w deklaracjach członków interfejsu.
  • Członkowie wyliczenia domyślnie mają publicznie zadeklarowaną dostępność. Żadne modyfikatory dostępu nie są dozwolone w deklaracjach członków wyliczenia.

(Należy zauważyć, że typy zagnieżdżone będą znajdować się pod częściami „członków klasy” lub „członków struktury” - i dlatego są domyślnie widoczne dla prywatności).


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
Nie wyjaśnia to, że jeśli klasa jest również członkiem (z uwagi na to, że jest typem zagnieżdżonym), wówczas domyślnie jest to prywatna. Ponadto członkowie interfejsu i wyliczenia są zawsze publiczni.
Jon Skeet

1
@niry Nie, to nie jest prywatne. To jest publiczne. Po prostu nie ma gniazda w typie implementacji, więc jeśli class Foo : IFoo { IFoo.M() {} } ... Foo a = new Foo();nie możesz uzyskać dostępu za Mpomocą a.M(), możesz to zrobić za pomocą (a as IFoo).M(). (Sprawdź specyfikację, aby uzyskać więcej informacji na temat szczegółów)
M.Stramm

130

Krótka odpowiedź: minimalny możliwy dostęp (por. Odpowiedź Jona Skeeta).

Długa odpowiedź:

Nie zagnieżdżone typy, wyliczanie i delegowanie dostępu ( może mieć tylko dostęp wewnętrzny lub publiczny )

                     | 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

Dostępność typu zagnieżdżonego i członków

                     | 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)

¹ Wszystkie === publiczne, chronione, wewnętrzne, prywatne, chronione wewnętrzne

² struktury nie mogą dziedziczyć po strukturach lub klasach (chociaż mogą, interfejsy), dlatego chroniony nie jest poprawnym modyfikatorem

Dostępność typu zagnieżdżonego zależy od jego domeny dostępności, która jest określona zarówno przez deklarowaną dostępność członka, jak i domenę dostępności typu zawierającego bezpośrednio. Domena dostępności typu zagnieżdżonego nie może jednak przekraczać domeny typu zawierającego.

Uwaga: CIL ma również opcję chronioną i wewnętrzną (w przeciwieństwie do istniejącej chronionej lub wewnętrznej), ale o ile wiem, nie jest obecnie dostępna do użycia w języku C #.


Widzieć:

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 URIs ...)


12

Spójrz na Modyfikatory dostępu (Podręcznik programowania w języku C #)

Dostępność klasy i struktury

Klasy i struktury zadeklarowane bezpośrednio w przestrzeni nazw (innymi słowy, które nie są zagnieżdżone w innych klasach lub strukturach) mogą być publiczne lub wewnętrzne. Wewnętrzny jest domyślny, jeśli nie określono modyfikatora dostępu.

Elementy struktury, w tym zagnieżdżone klasy i struktury, można zadeklarować jako publiczne, wewnętrzne lub prywatne. Członkowie klasy, w tym zagnieżdżone klasy i struktury, mogą być publiczni, chronieni wewnętrznie, chronieni, wewnętrzni, prywatni chronieni lub prywatni. Poziom dostępu dla członków klas i struktur, w tym klas zagnieżdżonych i struktur, jest domyślnie prywatny. Prywatne typy zagnieżdżone nie są dostępne spoza typu zawierającego.

Klasy pochodne nie mogą mieć większej dostępności niż ich typy podstawowe. Innymi słowy, nie możesz mieć publicznej klasy B, która pochodzi z wewnętrznej klasy A. Gdyby to było dozwolone, spowodowałoby to upublicznienie A, ponieważ wszyscy chronieni lub wewnętrzni członkowie A są dostępni z klasy pochodnej.

Możesz włączyć określone inne zespoły, aby uzyskać dostęp do typów wewnętrznych za pomocą InternalsVisibleToAttribute. Aby uzyskać więcej informacji, zobacz Zespoły znajomych.

Dostępność członka klasy i struktury

Członkowie klasy (w tym zagnieżdżone klasy i struktury) można zadeklarować za pomocą dowolnego z sześciu rodzajów dostępu. Elementy struktury nie mogą być deklarowane jako chronione, ponieważ struktury nie obsługują dziedziczenia.

Zwykle dostępność członka nie jest większa niż dostępność typu, który go zawiera. Jednak członek publiczny klasy wewnętrznej może być dostępny spoza zestawu, jeśli członek implementuje metody interfejsu lub zastępuje metody wirtualne zdefiniowane w publicznej klasie bazowej.

Typ dowolnego elementu będącego polem, właściwością lub zdarzeniem musi być co najmniej tak samo dostępny, jak sam element. Podobnie typ zwracany i typy parametrów dowolnego elementu będącego metodą, indeksatorem lub delegatem muszą być co najmniej tak samo dostępne, jak sam element członkowski. Na przykład nie możesz mieć publicznej metody M, która zwraca klasę C, chyba że C jest również publiczna. Podobnie nie można mieć chronionej właściwości typu A, jeśli A jest zadeklarowane jako prywatne.

Operatory zdefiniowane przez użytkownika muszą zawsze być deklarowane jako publiczne i statyczne. Aby uzyskać więcej informacji, zobacz Przeciążenie operatora.

Finalizatory nie mogą mieć modyfikatorów dostępności.

Inne rodzaje

Interfejsy zadeklarowane bezpośrednio w przestrzeni nazw mogą być zadeklarowane jako publiczne lub wewnętrzne i, podobnie jak klasy i struktury, interfejsy mają domyślny dostęp wewnętrzny. Członkowie interfejsu są zawsze publiczni, ponieważ celem interfejsu jest umożliwienie innym typom dostępu do klasy lub struktury. Do elementów interfejsu nie można stosować żadnych modyfikatorów dostępu.

Członkowie wyliczenia są zawsze publiczni i nie można stosować żadnych modyfikatorów dostępu.

Delegaci zachowują się jak klasy i struktury. Domyślnie mają dostęp wewnętrzny, gdy są zadeklarowane bezpośrednio w przestrzeni nazw, a dostęp prywatny po zagnieżdżeniu.


8

Klasa jest domyślnie Wewnętrzna .

  • Członkowie klasy są domyślnie prywatni .

Domyślnie interfejs jest wewnętrzny .

  • Członkowie interfejsu są domyślnie publiczni . (Interfejsy nie pozwalają nam określić żadnego rodzaju dostępu do jego członków).

    Uwaga: Jeśli spróbujesz podać dowolny specyfikator dostępu do członków interfejsu, wyświetli się błąd kompilacji.

Struktura jest domyślnie Wewnętrzna .

  • Członkowie struktury są domyślnie prywatni .

5

Chciałbym dodać link do dokumentacji. Sprawdź więcej szczegółów tutaj .

wprowadź opis zdjęcia tutaj


1
klasa jest domyślnie wewnętrzna i nieprywatna.
Baahubali,

1
Gdzie napisałem lekcja jest prywatna?
Asif Mushtaq,

Ta tabela jest ważna tylko dla typów zagnieżdżonych.
BlueSilver

klasa jest domyślnie wewnętrzna, a klasa wewnątrz przestrzeni nazw nie może być prywatna. ale klasa wewnątrz klasy (klasa zagnieżdżona) może być prywatna
Arun

Modyfikatorem dostępu interfejsu jest domyślnie Wewnętrzny .
Kamala Hanchinal

4

Najprostsza odpowiedź jest następująca .....

Wszyscy członkowie w C # zawsze domyślnie korzystają z MOŻLIWEGO dostępnego modyfikatora.

Dlatego wszystkie klasy najwyższego poziomu w zestawie są domyślnie „wewnętrzne”, co oznacza, że ​​są publiczne dla zestawu, w którym się znajdują, ale są prywatne lub wykluczone z dostępu do zewnętrznych zestawów. Jedyną inną opcją dla klasy najwyższego poziomu jest publiczna, która jest bardziej dostępna. W przypadku typów zagnieżdżonych wszystko jest prywatne, z wyjątkiem kilku rzadkich wyjątków, takich jak elementy wyliczeń i interfejsy, które mogą być tylko publiczne. Kilka przykładów. W przypadku klas i interfejsów najwyższego poziomu wartości domyślne to:

klasa Animal taka sama jak klasa wewnętrzna Animal

interfejs Animal taki sam jak interfejs publiczny Animal

W przypadku zagnieżdżonych klas i interfejsów (typy wewnętrzne) wartości domyślne to:

klasa Animal taka sama jak klasa prywatna Animal

interfejs Animal taki sam jak prywatny interfejs Animal

Jeśli po prostu założysz, że domyślna jest zawsze najbardziej prywatna, nie musisz używać akcesoriów, dopóki nie musisz zmienić domyślnej. Łatwy.



Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.