Czy jest jakiś powód, aby pisać słowo kluczowe „prywatne” w języku C #?

109

O ile mi wiadomo, privatejest domyślnym wszędzie w C # (co oznacza, że jeśli nie piszę public, protected, internal, itd. To będzie privatedomyślnie). (Proszę, popraw mnie jeśli się mylę.)

Więc jaki jest powód napisania tego słowa kluczowego lub dlaczego w ogóle istnieje ono dla członków?

Na przykład, gdy program obsługi zdarzeń jest generowany automatycznie, wygląda to tak:

private void RatTrap_MouseEnter(object sender, CheeseEventArgs e)
{

}

Ale dlaczego w ogóle pisze prywatne, jeśli jest to domniemane i domyślne? Tylko po to, aby początkujący programiści (którzy nie wiedzą, że jest to domyślne C #) wiedzą, że jest prywatny? A może jest różnica w kompilatorze?

Ponadto istnieje przypadek, w którym pisanie „prywatny” (samo) będzie zmieniać dostępności elementu?

Camilo Martin
źródło
18
IIRC, typ „najwyższego poziomu” będzie internaljednak domyślnie.
Jeff Mercado,
4
Domyślnie wszystko nie jest prywatne, jak wskazano, i zgodnie z ogólną zasadą lepiej jest to wyraźnie określić.
James Michael Hare
Domyślnie wszystko to „tak prywatne, jak to tylko możliwe”. Oczywiście niezagnieżdżona klasa nie może być prywatna ani nic nie może jej utworzyć instancji ani jej używać. Ale członkowie są domyślnie prywatne, a klasy zagnieżdżone są domyślnie prywatne. Wszystko w C # ma domyślnie najbardziej ograniczony poziom widoczności, jaki może mieć.
Ryan Lundy

Odpowiedzi:

171

AFAIK, private jest domyślne wszędzie w C # (co oznacza, że ​​jeśli nie napiszę publicznego, chronionego, wewnętrznego itp., Będzie domyślnie prywatne). (popraw mnie, jeśli się mylisz).

To nie jest prawda. Typy zdefiniowane w przestrzeni nazw (klasy, struktury, interfejsy itp.) Będą domyślnie wewnętrzne . Ponadto elementy członkowskie w różnych typach mają różne domyślne ułatwienia dostępu (takie jak publiczne dla elementów członkowskich interfejsu). Aby uzyskać szczegółowe informacje, zobacz Poziomy ułatwień dostępu w witrynie MSDN.

Również,

Więc jaki jest powód napisania tego słowa kluczowego lub dlaczego w ogóle istnieje?

Określenie tego wyraźnie pomaga wskazać zamiar uczynienia tego typu prywatnym, bardzo wyraźnie. Pomaga to w utrzymaniu kodu w czasie. Może to pomóc innym programistom (lub tobie) wiedzieć, czy członek jest domyślnie prywatny, czy celowo itp.

Reed Copsey
źródło
1
@Wayne: ma odpowiedź z wyższym wynikiem niż Jon Skeet, ale nie zasługuje na to ... Odpowiedź Jona jest o wiele dokładniejsza.
aleroot
2
To bezcelowe wyróżnienie. Typy w przestrzeni nazw są domyślnie wewnętrzne, ponieważ domyślnie nie mogą być prywatne; inaczej nic by ich nie wykorzystało. Domyślnie nadal są tak ograniczone, jak to tylko możliwe.
Ryan Lundy
1
Domyślna dostępność elementów członkowskich dla klas i struktury inisde jest prywatna. Sprawdź tutaj: msdn.microsoft.com/en-us/library/ba0a1yw2(v=vs.90).aspx
Mitja Bonca,
Ale elementy wewnątrz przestrzeni nazw nie mogą private.
Shimmy Weitzhandler
Ponadto, geti setdomyślna dostępność samej nieruchomości
AustinWBryan
119

AFAIK, prywatne jest domyślne wszędzie w C #

Niezupełnie - domyślnie jest to „najbardziej ograniczony dostęp dostępny dla tej deklaracji”. Na przykład dla typu najwyższego poziomu domyślną wartością jest internal; dla typu zagnieżdżonego wartością domyślną jest private.

Więc jaki jest powód napisania tego słowa kluczowego lub dlaczego w ogóle istnieje?

Wyraża to wyraźnie, co jest dobre z dwóch powodów:

  • To sprawia, że ​​jest to jaśniejsze dla tych, którzy nie znają wartości domyślnych, jak na twoje pytanie (osobiście nigdy nie podobał mi się ten argument, ale pomyślałem, że warto o nim wspomnieć)
  • Sprawia wrażenie, że celowo zdecydowałeś się uczynić go prywatnym, zamiast po prostu przejść z domyślnymi.

Jeśli chodzi o ostatnią część:

Co więcej, czy istnieje przypadek, w którym zapis „prywatny” (sam) zmieni dostępność członka?

Tak, za uczynienie połowy nieruchomości bardziej restrykcyjną niż druga:

// Public getter, public setter
public int Foo { get; set; }

// Public getter, private setter
public int Bar { get; private set; }

I wykorzystywane do przejść z domyślnych wszędzie mogłem, ale byłem przekonany (częściowo przez Eric Lippert), który czyni go wyczyścić, że już o tym myślał i postanowił zrobić coś prywatny jest dobrym pomysłem.

Osobiście żałuję, że nie ma sposobu na zrobienie tego również dla zapieczętowanych / nieopieczętowanych również dla deklaracji typu - prawdopodobnie nawet nie mają wartości domyślnej. Podejrzewam, że wielu programistów (łącznie ze mną, jeśli nie jestem ostrożny) pozostawia otwarte klasy tylko dlatego, że jest to mniej wysiłku niż ich zapieczętowanie.

Jon Skeet
źródło
+1. Używanie nieistotnych w inny sposób słów kluczowych do sygnalizowania intencji semantycznej jest przydatne, chociaż moje tło Java wykorzystuje finalbardziej typowy przykład.
jprete
1
@minitech: W drugą stronę też działa, ale jest mniej przydatne. To wszystko zostało wprowadzone w C # 2.
Jon Skeet,
20
Z pewnością chciałbym, aby w ogóle nie było żadnych wartości domyślnych, a kompilator po prostu wyrzucał błąd, jeśli brakowało modyfikatora dostępu. Myślę, że większość ludzi nie wie, jakie są wartości domyślne dla każdej sytuacji, co prowadzi do niezamierzonych błędów.
+1 „dla typu zagnieżdżonego domyślnie jest prywatny” - po prostu wiem o tym, gdy czytam twoją odpowiedź. Dzięki!
Nordin
5
@Phong, dla C # jest jedna prosta reguła: Domyślnie wszystko jest tak prywatne, jak to tylko możliwe. Elementy w przestrzeni nazw, takie jak niezagnieżdżone klasy, nie mogą być prywatne, ponieważ nic nie może ich używać. Mogą być tylko wewnętrzne lub publiczne; więc domyślnie są wewnętrzne. Rzeczy wewnątrz innych rzeczy (wyliczenia w klasie; zagnieżdżone klasy; właściwości; pola; metody ...) są domyślnie prywatne.
Ryan Lundy
11

privatedodaje wizualnego bałaganu. Tych, którzy nalegają, aby to wyjaśniało, zapytam: czy robisz to również z matematyką? Na przykład:

var answer = a + b / c;

Czy uważasz to za niejasne bez zbędnych nawiasów wokół b / c?

Zasada w C # jest bardzo prosta: domyślnie wszystko jest tak zbliżone do prywatnego, jak to tylko możliwe. Jeśli więc chcesz, aby coś było bardziej widoczne niż domyślne, dodaj modyfikator. W przeciwnym razie nie dodawaj do kodu niepotrzebnych słów kluczowych.

Ryan Lundy
źródło
1
Zwykłem się z tym zgadzać, zanim zadałem pytanie. Ale niektórzy ludzie piszą VB, niektórzy C ++, niektórzy nawet F # (pochodzący z innych języków funkcjonalnych, takich jak Haskell, być może?), Lepiej niż w C #. Tak więc dla nich (i dla nas, jeśli zapomnimy o tym po 2 latach bez c #ingu) lepiej, jeśli metody dostępu są jawne. Nie lekceważ wpływu łatwego uczenia się na projekt, wielu programistów wywodzi się ze środowisk, które mogą nie odzwierciedlać wybranego narzędzia, i potrzebują pomocy w nauce, nawet w kodzie produkcyjnym, to wcale nie jest złe (a wiemy wiele bardzo zły kod C #, więc kilka pomocy też nam pomaga).
Camilo Martin,
3
Cóż, oczywiście, w VB wartości domyślne są okropne. Myślę, że domyślna widoczność jest Friendna przykład dla członków. C # robi swoje domyślne ustawienia widoczności we właściwy sposób: rzeczy są ustawione na najmniej widoczną możliwą, chyba że zostaną zmienione. Z tego, co udało mi się znaleźć, wydaje się, że to samo dotyczy C ++ (z wyjątkiem struktur). (Wydaje się, że nie jest to prawdą w przypadku F #.)
Ryan Lundy
6
Dziwne jest dla mnie, że tak wielu ludzi jest za tym var, ponieważ ogranicza to wizualny bałagan, a jednocześnie tak wielu ludzi opowiada się za bezcelowym pisaniem private.
Ryan Lundy
2
Posunąłbym się nawet do argumentu, że wizualny bałagan utrudnia czytelność!
binki
1
upvoted choć nie wolą używać nawiasów w przypadku Twojej przykład matematyki.
Marc 2377,
7

O ile wiem, prywatna jest domyślna wszędzie w C #

Jawne określenie jako prywatne oznacza, że wiesz, że jest ono prywatne. Nie tylko myśl, że tak jest, ponieważ o ile wiesz, jest to ustawienie domyślne. Oznacza to również, że ktoś, kto patrzy na kod, wie, co to jest.

Nie ma „Myślę, że tak”, „Jestem pewien, że tak jest” itd. Po prostu jest . I wszyscy są na tej samej stronie.

Nie jestem programistą C # . Gdybym musiał pracować z jakimś kodem, który nie został wyraźnie określony jako prywatny , prawdopodobnie założyłbym, że jest to kod wewnętrzny .

Nie lubię, gdy rzeczy są ustawione domyślnie. Nigdy nie jest tak jasne, jak wtedy, gdy są wyraźnie ustawione.

JD Isaacks
źródło
Brzmi rozsądnie, zapominam nawet o podstawach języków, które kiedyś znałem lepiej.
Camilo Martin
6

Czytelność - nie każdy może wiedzieć, że zachowanie prywatne jest domyślnym zachowaniem.

Zamiar - daje wyraźne wskazanie, że wyraźnie oznaczyłeś nieruchomość jako prywatną (z dowolnego powodu).

James
źródło
5

Czytelność, demonstracja intencji to dwa ważne powody, o których mogę pomyśleć.

Maess
źródło
Zgoda. Np. Jeśli pracujesz z innymi programistami nad fragmentem kodu, ustawienie czegoś na prywatne pomaga wskazać zamiar. Jest to również pomocne, gdy wskoczysz z powrotem do kodu po kilku latach i twoje IDE może powiedzieć ci, które metody powinny być publicznie dostępne dla tej klasy.
Aaron Newton
3

Jednym z dobrych powodów, aby wyraźnie określić widoczność, jest to, że nie musisz zastanawiać się, jaki jest domyślny kontekst, w którym się znajdujesz.

Innym dobrym powodem jest to, że FxCop każe ci to zrobić.

Patrick McDonald
źródło
+1, właśnie zauważyłem, że FxCop narzeka, że ​​usuwam prywatny modyfikator teraz, kiedy budowałem ze zmianą.
Camilo Martin,
2

Wiele osób (takich jak ja!) Regularnie programuje w kilku różnych językach. Mówienie wprost o takich rzeczach nie pozwala mi na zapamiętywanie wszystkich tajemniczych szczegółów wszystkich języków, w których programuję.

davidtbernal
źródło
1
Cóż, nie powiedziałbym, że „domyślny modyfikator dostępu to private” to tajemny szczegół ... Ale rozumiem, o co chodzi. Pewnego dnia miałem problemy z przypomnieniem sobie, jak działał framework, którego użyłem w zeszłym tygodniu ( MEF ).
Camilo Martin
0

Powiedziałbym za spójność z czytelnością zakresu reszty klasy.

MGZero
źródło
4
Myślisz o C ++. W C #, nawet w strukturach, członkowie domyślnie mają wartość private.
3
Struktury domyślnie nie mają publicznego dostępu - patrz: msdn.microsoft.com/en-us/library/ba0a1yw2.aspx
Reed Copsey