Jakie jest znaczenie planowanego modyfikatora dostępu C # „prywatnie chroniony”?


133

W ramach dokumentacji Roslyn w serwisie GitHub znajduje się strona o nazwie Stan implementacji funkcji języka z planowanymi funkcjami językowymi dla C # i VB.

Jedną z funkcji, której nie mogłem ogarnąć głowy, był private protectedmodyfikator dostępu:

private protected string GetId() {  } 

Istnieje również strona notatek projektowych języka C # , która wyjaśnia wiele nowych funkcji, ale nie tę.

Eric Lippert powiedział w komentarzu :

Twój błąd polega na myśleniu o modyfikatorach jako o rosnących ograniczeniach. W rzeczywistości modyfikatory zawsze zmniejszają ograniczenia. Pamiętaj, że rzeczy są domyślnie „prywatne”; tylko poprzez dodanie modyfikatorów sprawisz, że będą mniej ograniczone.

Jakie to ma znaczenie private protected? Kiedy mogę tego użyć?


2
Zwróć uwagę, że jest o tym informacja w uwagach do projektowania języka VB .
Jesse Good

3
Jest to mapowanie do MethodAttributes.FamANDAssem. C # ma dziwne mapowanie wewnętrznego , używa (Private | FamANDAssem). Oraz wewnętrzne chronione mapy do (Prywatne | Rodzinne). Atrybuty CLR są dziwne.
Hans Passant

22
Ta proponowana funkcja sprawi, że mój komentarz będzie nieprawidłowy.
Eric Lippert

Zespół projektowy C # opublikował ankietę z sugerowaną alternatywną składnią dla tej funkcji. Niektóre z nich są interesujące, jak protected & internal, assembly protectedlub proternal(mam nadzieję, że niektóre z nich są żarty). Jest też wątek Dyskusja z ciekawymi spostrzeżeniami.
Kobi

1
Funkcja jest teraz oznaczona jako wycofana w stanie implementacji funkcji językowej! Osobiście podoba mi się pomysł tego poziomu dostępu i uważam, że jest to użyteczna funkcja. Chcę używać chronionych, aby zachować mój kod zgodnie z projektem klasy, ale nie chcę, aby inni pisali hacky podklasy, które mają dostęp do tych członków. IMO najlepszym rozwiązaniem byłoby, gdybyśmy mogli napisać protected | internaliprotected & internal
Felix Keil

Odpowiedzi:


98

Według „ Professional C # 2008 ” De Billa Evjena i Jaya Glynna, strona 1699:

prywatnie chroniony - „tylko typy pochodne w bieżącym zestawie”

C ++ / CLI ma podobną funkcję - Definiuj i używaj klas i struktur (C ++ / CLI)> Widoczność elementu członkowskiego :

private protected-lub- protected private- Element jest chroniony wewnątrz zespołu, ale poza zespołem.


72
Czyli jest „chroniony i wewnętrzny” zamiast „chroniony lub wewnętrzny”?
user541686

2
Czy teraz będzie możliwe, aby element członkowski dostępny dla klas pochodnych akceptował lub zwracał elementy internaltypu bez wymagania, aby element członkowski był widoczny dla wszystkiego w zestawie?
supercat

Dzięki! Nie myślałem o tym. Właściwie mam przypadki, w których użyłbym tego modyfikatora i wróciłem internal.
Kobi

3
Istnienie tej propozycji / funkcji wydaje się sugerować, że internalwidoczność (związana z tym, gdzie zdefiniowano klasę) jest naprawdę ortogonalna do public/ protected/ privatewidoczność (związana z dziedziczeniem) i być może internalpowinna być własnym modyfikatorem niezależnym od public/ protected/ private.
jpmc26

1
@jww - Nie znam Javy, ale o ile wiem, packagew Javie bardziej przypomina przestrzeń nazw w C #.
Gogutz

187

Oto wszystkie modyfikatory dostępu na diagramach Venna, od bardziej ograniczających po bardziej rozwiązłe:

private:
wprowadź opis obrazu tutaj

private protected: - dodane w C # 7.2
wprowadź opis obrazu tutaj

internal:
wprowadź opis obrazu tutaj

protected:
wprowadź opis obrazu tutaj

protected internal:
wprowadź opis obrazu tutaj

public:
wprowadź opis obrazu tutaj


3
Obraz źródłowy: Access Modifiers.pdn . Użyłem trafnie nazwanego Paint.Net .
Kobi,

9
Gdzie te diagramy były przez całe moje (C #) życie? Są znakomite - dziękuję!
Jon Peterson

28

Ma to na celu jedynie przedstawienie wykresu (utworzonego za pomocą http://ashitani.jp/gv/ ) różnych poziomów dostępności (obrazy nie mieszczą się w komentarzach).

diagram dwuznakowy poziomów dostępu C #

Każda strzałka oznacza „jest bardziej restrykcyjna niż”.

Nazwy są CLR Private, FamilyANDAssembly, Assembly, Family, FamilyORAssembly, Public.


Znacznie późniejsza edycja: Okazało się, że ten fajny nowy poziom dostępu (o bardzo złej nazwie) nie został ostatecznie uwzględniony w C # 6.0. Jest obsługiwany tylko od wersji C # 7.2 (i widzę, że zaktualizowałeś swoje pytanie „tagi”).


Może to tylko ja, ale wydaje się, że strzały zmierzają w kierunku „mniej restrykcyjnym niż”.
acarlon

4
@acarlon Tak, więc a → bna schemacie oznacza „ ajest bardziej restrykcyjny niż b”, więc możesz „czytać” strzałkę jako „jest bardziej restrykcyjny niż„ (to właśnie próbowałem wyjaśnić), więc strzałka wskazuje w najmniejszym stopniu ” kierunek". Nawiasem mówiąc, przeciwna konwencja dla strzał mogła być równie dobra, ale musiałem wybrać jedną konwencję.
Jeppe Stig Nielsen

10

To tylko przypuszczenie, ale z nazwy można się domyślić, że jest to bardziej ograniczona wersja protected(lub bardziej zrelaksowana wersja, privatejeśli chcesz). Jedynym rozsądnym wariantem jest ograniczenie protectedzachowania do montażu.

Możliwe użycie: wtedy chcesz mieć protecteddo implementacji wewnętrznej, ale nie do użytku zewnętrznego (i nie chcesz zapieczętować klasy).

PS Zawsze istniał w środowisku CLR, ale nie w C # . To połączenie protected i internal , cytuj:

CLR obsługuje również typ dostępu „Rodzina i zespół”. Oznacza to, że metoda jest dostępna z poziomu deklarującego typu, typów zagnieżdżonych i pochodnych, ale tylko wtedy, gdy są zadeklarowane w tym samym zestawie. Najwyraźniej zespół C # nie pomyślał o tym jako o bardzo użytecznej funkcji, więc nie jest obsługiwana w tym języku.


+1 dla komentarza CLR - Obecnie spędzam tak dużo czasu w C #, a tak mało w innych językach .NET, że czasami zapominam, że to nie to samo.
brichins,

@DarrelHoffman dzięki za uwagę! Tu trochę pomieszałem swoje myśli)
Petr Abdulin

5

„Może być” widoczne tylko dla podklas, które są w tym samym zestawie. To sprawia, że ​​jest trochę ograniczony niż protected.


1

Zobacz specyfikację funkcji „private protected”:

Intuicyjne znaczenie prywatnej ochrony jest „dostępne w ramach tego zestawu według typów pochodnych klasy zawierającej”.

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.