2009-11-09 14 views
5

W Visual Studio 2008 Team System, po prostu uruchomiłem analizę kodu (z menu analizy) w jednym z moich projektów C#. Jednym z ostrzeżeń produkowanych był następujący:C# pole chronione jako prywatne, dodaj właściwość - dlaczego?

Microsoft.Design: Ponieważ pole „Connection._domain” jest widoczny na zewnątrz tego typu stwierdzającej, zmienić jego dostęp do prywatnych i dodać obiekt, z tym samym dostępności jako dziedzinie ma obecnie dostęp do niej.

To odnosi się do następujących dziedzinach:

public abstract class Connection 
{ 
    protected string _domain; 
} 

Nie rozumiem uzasadnienie sugestii. To jest to, co myślę, że chce mi zrobić:

public abstract class Connection 
{ 
    private string _domain; 
    protected string Domain { get { return _domain; } set { _domain = value; } } 
} 

dwa pytania:

  1. Czy dobrze rozumiem, co sugestia chce mi zrobić, kod mądry?
  2. Dlaczego chce, abym to zrobił?
+0

Zobacz także http://stackoverflow.com/questions/1410645/are-public-fields-ever-ok, http://stackoverflow.com/questions/480627/why-wont-anyone-accept-public-fields -in-c, http://stackoverflow.com/questions/1277572/should-i-use-public-properties-and-private-fields-or-public-fields-for-data i kilka innych (szukaj na stronie publicznej pola "). Wszyscy omawiają dziedziny publiczne, ale ogólnie odnoszą się również do pól chronionych. –

Odpowiedz

13

Tak, myślę, że zrozumiałem - choć w nowszych wersjach C#, jest bardziej zwięzły sposób, żeby to napisać:

public string Domain { get; set; } 

Dlaczego? Chodzi o hermetyzację. Jeśli zrobisz to, co sugerujesz, możesz później zmienić definicję właściwości domeny bez wpływu na kod wywołujący, który korzysta z tej właściwości. Ponieważ twoja klasa jest publiczna i można ją nazwać kodem, którego nie pisałeś, jest to potencjalnie dość ważne.

+0

w jego przypadku, 'protected string Domain {get; zestaw; } ' – nawfal

2

Tak. Taka jest sugestia. Nie powinnaś mieć żadnej dostępności wyższej niż prywatne odsłonięte jako bezpośrednie pola instancji.

Jest to jedna z głównych zasad OOD - hermetyzacja określana również jako "ukrywanie danych".

2
  1. Tak, poprawiono kod błędu.
  2. Chodzi o hermetyzację. _domain to dane o twoim obiekcie. Zamiast eksponować je bezpośrednio, aby dowolny klient miał niefiltrowany dostęp, należy udostępnić interfejs umożliwiający mu dostęp. Praktycznie może to być dodanie sprawdzania poprawności do ustawiacza, aby nie można było ustawić żadnej wartości. Wydaje się to głupie, jeśli jesteś jedynym piszącym kodem, ponieważ wiesz, jak działa Twój interfejs API. Ale spróbuj pomyśleć o rzeczach na dużym poziomie przedsiębiorstwa, lepiej jest mieć API, aby twój obiekt mógł być postrzegany jako pudełko, które akompaniuje zadanie. Można powiedzieć, że nigdy nie będziesz potrzebował dodawać czegoś takiego jak sprawdzanie poprawności do tego obiektu, ale rzeczy robione są w ten sposób, aby zachować możliwość tego, a także być spójne.
2

Dzieje się tak dlatego, że jeśli kiedykolwiek chciałbyś zmienić pole na właściwość w przyszłości, złamiesz wszystkie inne zespoły, które od niego zależą.

Dobrą praktyką jest utrzymywanie wszystkich pól jako prywatnych i zawijanie ich we właściwości, aby w przyszłości można było dodać walidację lub inną logikę bez rekompilacji wszystkich konsumentów (lub w tym przypadku spadkobierców) z klasy.

+0

Dlaczego upadek? Technicznie to prawda. IL dostępu do pola różni się od dostępu do właściwości. Jeśli skompilujesz zespół (A), który odwołuje się do pól w innym zespole (B), a następnie zaktualizuje zestaw (B) i zmieni pola na właściwości, wówczas zespół (A) zostanie uszkodzony. – Bob

+0

Zgadzam się, Bob, uważam, że jest to bardzo ważny czynnik. (+1) Zmiana pola na właściwość (ponieważ chcesz dodać logikę sprawdzania poprawności lub rejestrowania lub chcesz uczynić ją wirtualną lub z jakiegokolwiek innego powodu) może być binarną zmianą łamania dla wszystkich użytkowników klasy. Prawdopodobnie jest to również złamanie poziomu źródłowego, jeśli nazwiesz małe litery i wielkie litery właściwości, tak jak konwencja. – Joren

+0

I to jest powód, dla którego powinieneś używać właściwości. Gdyby tak nie było, nie byłoby powodu, aby korzystać z nieruchomości, dopóki nie zdecydujesz, że ich potrzebujesz. Myślałem, że to odpowiada na pytanie/wzruszam ramionami :) – GraemeF

2

Twoje tłumaczenie jest prawidłowe.Ten sam argument można argumentować za używaniem właściwości "chronionych", ponieważ można je wykorzystać do używania właściwości "publicznych", zamiast bezpośrednio wystawiać zmienne członkowskie.

Jeśli to tylko prowadzi do rozprzestrzeniania się prostych programów pobierających i ustawiających, to myślę, że uszkodzenie odczytu kodu przewyższa korzyści wynikające z możliwości zmiany kodu w przyszłości. Wraz z rozwojem właściwości kompilatora generowane w C# to nie jest aż tak źle, wystarczy użyć:

protected string Domain { get; set; } 
0

W odpowiedzi na to pytanie ... Tak.

Chciałbym jednak wystarczy użyć składni auto właściwość:

public abstract class Connection 
{ 
    protected string Domain { get; set; } 
} 
0

Zasadniczo właściwości zapewniają ponad powrocie lub ustawienie elementu. Pozwalają one na dodanie logiki, która mogłaby zweryfikować poprawność formatu wejściowego, walidację zakresu itp.

Wybrana odpowiedź z linku mówi najlepiej: "Właściwości zapewniają enkapsulację." Można zawrzeć dowolne wymagane sprawdzanie/formatowanie/konwersję w kod dla nieruchomości, co byłoby trudne dla pól. "

http://social.msdn.microsoft.com/Forums/en-IE/netfxbcl/thread/985f4887-92ae-4ec2-b7ae-ec8cc6eb3a42

0

Oprócz innych odpowiedzi wymienionych tutaj, public/protected członków, które zaczynają się od podkreślenia nie są CLS-compliant, że nie ma wymogu dla języków .NET wspieranie członków z wiodących podkreślenia, więc ktoś dziedziczenie z klasy w innym języku .NET może nie być w stanie uzyskać dostępu do danego chronionego członka.

Wiem, prawdopodobnie nie dotyczy to Ciebie, ale może to być jeden z powodów ostrzeżenia o analizie kodu.