Często mówi się nam, że powinniśmy chronić enkapsulację, tworząc metody getter i setter (właściwości w języku C #) dla pól klas, zamiast wystawiać pola na świat zewnętrzny.
Ale wiele razy pole jest tam tylko po to, by przechowywać wartość i nie wymaga obliczeń, aby uzyskać lub ustawić. Dla tych wszystkich zrobilibyśmy tę liczbę:
public class Book
{
private string _title;
public string Title
{
get{ return _title; }
set{ _title = value; }
}
}
Cóż, mam spowiedź, nie mogłem znieść pisania tego wszystkiego (tak naprawdę nie musiałem tego pisać, musiałem na to popatrzeć), więc zbuntowałem się i korzystałem z publicznych pól.
Potem pojawia się C # 3.0 i widzę, że dodali właściwości automatyczne:
public class Book
{
public string Title {get; set;}
}
co jest bardziej uporządkowane i jestem za to wdzięczny, ale tak naprawdę, co takiego różni się od zwykłego tworzenia pola publicznego?
public class Book
{
public string Title;
}
c#
class
properties
field
automatic-properties
IJ Kennedy
źródło
źródło
prop
Fragment kodu pozwala szybko tworzyć właściwości. Po prostu wpiszprop
i tab.Odpowiedzi:
W pokrewnym pytaniu, które miałem jakiś czas temu, był link do posta na blogu Jeffa, wyjaśniający pewne różnice.
Właściwości a zmienne publiczne
Zmiana zmiennej na właściwość jest przełomową zmianą. Na przykład:
źródło
ref
lubout
słowo kluczowe), podczas gdy właściwość jest parą akcesoriów i nie może być przekazana przez referencję. Na przykład,bool success = TryGetMyTitle(out myBook.Title);
które zastosowaniaout
będą działać z polem, a nie z właściwością. To wyraźny przykład tego, dlaczego zmiana z pola na właściwość jest przełomową zmianą!ref
/out
, a następnie ustawić właściwość na wartość, którą ma zmienna lokalna. Ale wtedy wywoływana metoda sama nie uzyskuje dostępu do właściwości, uzyskuje dostęp do lokalnej zmiennej, którą tam utworzyłeś.public int Foo { get; }
co spowoduje utworzenie właściwości automatycznej z polem tylko do odczytu.Ignorując problemy z interfejsem API, najcenniejszą rzeczą w korzystaniu z właściwości jest debugowanie.
Debuger CLR nie obsługuje punktów przerwania danych (większość macierzystych debugerów to robi). Dlatego nie jest możliwe ustawienie punktu przerwania dla odczytu lub zapisu określonego pola w klasie. Jest to bardzo ograniczone w niektórych scenariuszach debugowania.
Ponieważ właściwości są implementowane jako bardzo cienkie metody, możliwe jest ustawienie punktów przerwania na odczyt i zapis ich wartości. To daje im dużą nogę nad polami.
źródło
Zmiana pola na właściwość powoduje zerwanie kontraktu (np. Wymaga ponownej kompilacji całego kodu odniesienia). Więc kiedy masz punkt interakcji z innymi klasami - dowolnym publicznym (i ogólnie chronionym) członkiem, chcesz zaplanować przyszły rozwój. Rób to zawsze, używając właściwości.
Nie ma dziś nic, co mogłoby uczynić z niego auto-własność, a 3 miesiące później zdałem sobie sprawę, że chcesz sprawić, by był leniwy i wystawił kontrolę zerową w getterze. Jeśli użyłeś pola, jest to zmiana rekompilacji w najlepszym wypadku, aw najgorszym niemożliwa, w zależności od tego, kto i co jeszcze zależy od twoich zespołów.
źródło
Tylko dlatego, że nikt o tym nie wspominał: nie można definiować pól w interfejsach. Tak więc, jeśli musisz wdrożyć określony interfejs, który definiuje właściwości, auto-właściwości czasami są naprawdę fajną funkcją.
źródło
Ogromna różnica, która jest często pomijana i nie jest wymieniona w żadnej innej odpowiedzi: zastąpienie . Możesz zadeklarować właściwości wirtualne i zastąpić je, podczas gdy nie możesz zrobić tego samego dla publicznych pól członkowskich.
źródło
Chodzi o wersjonowanie i stabilność API. Nie ma różnicy w wersji 1 - ale później, jeśli zdecydujesz, że musisz to uczynić właściwością z pewnego rodzaju sprawdzaniem błędów w wersji 2, nie musisz zmieniać interfejsu API - żadnych zmian kodu, gdziekolwiek, poza definicja nieruchomości.
źródło
Kolejną zaletą automatycznie zaimplementowanych właściwości w porównaniu z polami publicznymi jest to, że można ustawić prywatnie lub chroniony zestaw akcesoriów, zapewniając klasę obiektów, w których zdefiniowano, lepszą kontrolę niż w przypadku pól publicznych.
źródło
W tworzeniu pola nie ma nic złego
public
. Ale pamiętaj, tworzącgetter/setter
zprivate
pól ma enkapsulacji. IMO, jeśli nie przejmujesz się innymi funkcjamiProperty
, równie dobrze możesz to zrobićpublic
.źródło
Jeśli później zdecydujesz się sprawdzić, czy tytuł jest unikalny, porównując z kolekcją lub bazą danych, możesz to zrobić we właściwości bez zmiany zależnego od niej kodu.
Jeśli wybierzesz tylko atrybut publiczny, będziesz mieć mniejszą elastyczność.
Dodatkowa elastyczność bez zerwania umowy jest dla mnie najważniejsza w korzystaniu z właściwości i, dopóki faktycznie nie potrzebuję elastyczności, automatyczne generowanie ma sens.
źródło
Jedną z rzeczy, które uważam za bardzo przydatne, podobnie jak cały kod i powody testowania, jest to, że jeśli jest to właściwość kontra pole, to Visual Studio IDE pokazuje referencje do właściwości, ale nie pola.
źródło
Mój pow później zrobił kilka badań
To naprawdę daje nam więcej możliwości i możliwości rozszerzenia.
źródło