Jaka jest różnica między „chronionym” a „chronionym wewnętrznym”?

244

Czy ktoś może mi wyjaśnić różnicę między „chronionymi” i „chronionymi wewnętrznymi” modyfikatorami w języku C #? Wygląda na to, że zachowują się w ten sam sposób.

Embedd_Khurja
źródło

Odpowiedzi:

402

„Chroniony wewnętrzny” modyfikator dostępu to połączenie zarówno „chronionych”, jak i „wewnętrznych” modyfikatorów.

Od MSDN, modyfikatory dostępu (Podręcznik programowania w języku C #) :

chronione :

Dostęp do typu lub elementu można uzyskać tylko za pomocą kodu w tej samej klasie lub strukturze lub w klasie pochodnej od tej klasy.

wewnętrzne :

Dostęp do typu lub elementu można uzyskać za pomocą dowolnego kodu w tym samym zestawie, ale nie z innego zestawu.

chroniony wewnętrzny :

Dostęp do typu lub elementu można uzyskać za pomocą dowolnego kodu w zestawie, w którym został zadeklarowany, LUB z poziomu klasy pochodnej w innym zestawie. Dostęp z innego zestawu musi odbywać się w ramach deklaracji klasy, która wywodzi się z klasy, w której zadeklarowany jest chroniony element wewnętrzny, i musi odbywać się za pośrednictwem instancji klasy pochodnej.

Zauważ, że : protected internaloznacza „ protectedLUB internal” (dowolna klasa w tym samym zestawie lub dowolna klasa pochodna - nawet jeśli jest w innym zestawie).

... i dla kompletności:

prywatny :

Dostęp do typu lub elementu można uzyskać tylko za pomocą kodu w tej samej klasie lub strukturze.

publiczne :

Dostęp do typu lub elementu można uzyskać za pomocą dowolnego kodu w tym samym zestawie lub innym zestawie, który się do niego odwołuje.

prywatny chroniony :

Dostęp jest ograniczony do zawierającej klasy lub typów pochodnych z zawierającej klasy w bieżącym zestawie.
( Dostępne od wersji C # 7.2 )

M4N
źródło
2
Czy mogę mieć członka, protected internalaby znajdował się protectedw bieżącym zespole i był całkowicie niedostępny na zewnątrz?
Shimmy Weitzhandler
8
To byłoby „chronione”, prawda?
CAD bloke
2
@Shimmy: możesz mieć wewnętrzną klasę z chronionymi metodami . Ale wtedy cała klasa będzie niedostępna z zewnętrznych zespołów.
M4N
1
@Shimmy zapoznaj się z tą propozycją dotyczącą przyszłej wersji C # github.com/dotnet/roslyn/blob/features/privateProtected/docs/…
Nate Cook
@Shimmy Przynajmniej CLR obsługuje koncepcję przecięcia chronionej i wewnętrznej dostępności, ale język C # nie. C # obsługuje tylko połączenie dwóch modyfikatorów dostępu.
RBT
89

protected mogą być używane przez dowolne podklasy z dowolnego zestawu.

protected internaljest wszystkim, co protectedjest, a także wszystko w tym samym zestawie może uzyskać do niego dostęp.

Co ważne, nie oznacza to „podklas w tym samym zespole” - jest to połączenie dwóch, a nie skrzyżowanie.

Marc Gravell
źródło
3
Tylko informacja dla czytelników, że CLR obsługuje również koncepcję przecięcia chronionej i wewnętrznej dostępności, ale C # nie obsługuje tego. C # obsługuje tylko połączenie tych dwóch, jak wspomniano w tym poście.
RBT
1
Kolejna informacja dla czytelników: „podklasy w tym samym zestawie” można uzyskać za pomocą private protectedmodyfikatora dostępu, który został wprowadzony w C # 7.2
LordWilmore
52

- Zaktualizuj odpowiedź 2019 -

Różnicę w dostępności poniżej tabeli można znaleźć tak,

wprowadź opis zdjęcia tutaj

Andi AR
źródło
4
Piękna odpowiedź, bardzo wyraźnie komunikuje różnice między każdym modyfikatorem dostępu.
e_i_pi
23

W praktyce o metodach:

chroniony - dostępny dla klas odziedziczonych, w przeciwnym razie prywatnych.

wewnętrzny - publiczny tylko dla klas wewnątrz zestawu, poza tym prywatny.

chronione wewnętrzne - oznacza chronione lub wewnętrzne - metody stają się dostępne dla klas dziedziczonych i dla wszystkich klas wewnątrz zestawu.

abatishchev
źródło
1
Użyłbym OR, aby wyrazić tę przyczynę, albo to nie oba muszą być prawdą.
Brian Rasmussen
Nie do końca zgadzam się z częścią „zmieniającą zachowanie klasy podstawowej” w opisie „chronione”. Powiedziałbym, że tutaj używasz „wirtualnego” (w klasie bazowej) i „zastępowania” (w klasie pochodnej).
M4N
Czy istnieje sposób na oznaczenie członka jako protectedAND internal?
Shimmy Weitzhandler
@Shimmy: tak protected internal.
abatishchev
1
@Shimmy dwa lata później i tak. Teraz jest sposób w C # 7.2. Nazywa się private protected docs.microsoft.com/en-us/dotnet/csharp/language-reference/...
Pauli
10

Nadal istnieje wiele nieporozumień w zakresie rozumienia zakresu „chronionych wewnętrznych” akcesoriów, chociaż większość ma poprawnie zdefiniowaną definicję. Pomogło mi to zrozumieć zamieszanie między „chronionym” a „chronionym wewnętrznym”:

public jest naprawdę publiczny wewnątrz i na zewnątrz zgromadzenia ( public internal / public external )

Protected jest naprawdę chroniony wewnątrz i na zewnątrz zestawu ( chroniony wewnętrzny / chroniony zewnętrzny ) (niedozwolone w klasach najwyższego poziomu)

private jest naprawdę prywatne wewnątrz i na zewnątrz zestawu ( prywatne wewnętrzne / prywatne zewnętrzne ) (niedozwolone na klasach najwyższego poziomu)

wewnętrzny jest naprawdę publiczny w zespole, ale wykluczony poza nim, jak prywatny ( publiczny wewnętrzny / wykluczony zewnętrzny )

chroniony wewnętrzny jest naprawdę publiczny w zestawie, ale chroniony poza zestawem ( publiczny wewnętrzny / chroniony zewnętrzny ) (niedozwolone w klasach najwyższego poziomu)

Jak widać chroniony wewnętrzny to bardzo dziwna bestia. Nie intuicyjne.

To nasuwa teraz pytanie, dlaczego Microsoft nie stworzył ( chronionego wewnętrznego / wykluczonego zewnętrznego ), czy też wydaje mi się, że jakiś „chroniony prywatnie” lub „chroniony wewnętrznie”? lol. Wydaje się niekompletny?

Dodatkowym zamieszaniem jest fakt, że można zagnieżdżać publiczne lub chronione wewnętrzne elementy zagnieżdżone wewnątrz typów chronionych, wewnętrznych lub prywatnych. Dlaczego miałbyś uzyskać dostęp do zagnieżdżonego „chronionego wewnętrznego” wewnątrz klasy wewnętrznej, który wyklucza zewnętrzny dostęp do zestawu?

Microsoft twierdzi, że takie typy zagnieżdżone są ograniczone ich zakresem typów nadrzędnych, ale nie tak mówi kompilator. Możesz skompilować chronione elementy wewnętrzne w klasach wewnętrznych, które powinny ograniczyć zakres do samego zestawu.

Dla mnie to wydaje się niekompletne. Powinny mieć uproszczony zakres wszystkich typów w systemie, który wyraźnie uwzględnia dziedziczenie, ale także bezpieczeństwo i hierarchię typów zagnieżdżonych. To spowodowałoby, że udostępnianie obiektów byłoby wyjątkowo intuicyjne i szczegółowe, zamiast odkrywać dostępność typów i elementów opartych na niekompletnym systemie określania zakresu.

Stokely
źródło
1
Prywatna chroniona została teraz dodana do C # 7.2, która jest zasadniczo wewnętrzna ORAZ chroniona.
Pauli Østerø
7

chroniony : zmienna lub metoda będzie dostępna tylko dla klas potomnych (w dowolnym zestawie)

chronione wewnętrzne : dostępne dla klas potomnych w dowolnym zestawie i dla wszystkich klas w tym samym zestawie

Benzoes
źródło
3

Przeczytałem bardzo jasne definicje tych terminów.

Protected: Dostęp jest ograniczony do definicji klasy i każdej klasy dziedziczącej po klasie. Dostęp do typu lub elementu można uzyskać tylko za pomocą kodu w tej samej klasie lub strukturze lub w klasie pochodnej od tej klasy.

Wewnętrzne: dostęp jest ograniczony wyłącznie do klas zdefiniowanych w bieżącym zestawie projektu. Dostęp do typu lub elementu można uzyskać tylko za pomocą kodu w tej samej klasie.

Protected-Internal: Dostęp jest ograniczony do bieżącego zestawu lub typów pochodzących z zawierającej klasy.

Ammar Asjad
źródło
1

Członek chroniony

Członek chroniony klasy dostępny tylko w klasie zawartej (w której został zadeklarowany) oraz w klasie pochodnej w zestawie, a także poza zestawem.

Oznacza, że ​​klasa rezydująca poza zestawem może korzystać z chronionego elementu innego zestawu, dziedzicząc tylko tę klasę.

Możemy odsłonić element chroniony poza zestawem, odziedzicząc tę ​​klasę i używać go tylko w klasie pochodnej.

Uwaga: Chronione elementy nie są dostępne przy użyciu obiektu w klasie pochodnej.

Członek wewnętrzny

Wewnętrzny element członkowski klasy jest dostępny lub można go uzyskać w zestawie, tworząc obiekt lub w klasie pochodnej, lub można powiedzieć, że jest dostępny we wszystkich klasach w zestawie.

Uwaga: Elementy wewnętrzne niedostępne poza zestawem za pomocą tworzenia obiektów lub w klasie pochodnej.

Chroniony wewnętrzny

Protected Modyfikator dostępu wewnętrznego to połączenie Protected lub Internal.

Chroniony element wewnętrzny może być dostępny w całym zestawie, w którym zadeklarował tworzenie obiektu lub dziedziczenie tej klasy. I może być dostępny poza zestawem tylko w klasie pochodnej.

Uwaga: Chroniony element wewnętrzny działa jako wewnętrzny w tym samym zespole i działa jako chroniony na zewnątrz zespołu.

Mostafa Bouzari
źródło
1

public - Dostęp do członków (funkcji i zmiennych) zadeklarowanych jako public można uzyskać z dowolnego miejsca.

private - do prywatnych członków nie można uzyskać dostępu spoza klasy. Jest to domyślny specyfikator dostępu dla członka, tzn. Jeśli nie określisz specyfikatora dostępu dla członka (zmiennej lub funkcji), zostanie on uznany za prywatny. Dlatego ciąg PhoneNumber; jest równoważne z prywatnym ciągiem PhoneNumber.

chronione - Dostęp do chronionych członków można uzyskać tylko z klas podrzędnych.

wewnętrzna - Dostęp jest możliwy tylko w tym samym zestawie.

chronione wewnętrznie - można uzyskać do niego dostęp w tym samym zestawie, a także w klasie pochodnej.

Piush Shukla
źródło
0

Najlepsze wewnętrzne pakiety chronione, gdy chcesz, aby element lub typ był używany w klasie pochodnej z innego zestawu w tym samym czasie, po prostu chcesz zużyć element członkowski lub typ w zestawie nadrzędnym, nie wywodząc się z klasy, w której jest zadeklarowany. Również jeśli chcesz używać tylko elementu lub typu bez wywodzenia się z innej klasy, w tym samym zestawie możesz używać tylko wewnętrznego.

satishpkumarin
źródło