Właściwości a metody

135

Szybkie pytanie: Kiedy decydujesz się używać właściwości (w C #), a kiedy decydujesz się na metody?

Jesteśmy zajęci tą debatą i znaleźliśmy pewne obszary, w których jest dyskusyjne, czy powinniśmy użyć właściwości, czy metody. Oto jeden przykład:

public void SetLabel(string text)
{
    Label.Text = text;
}

W tym przykładzie Labeljest kontrolką na stronie ASPX. Czy istnieje zasada, która może regulować decyzję (w tym przypadku), czy uczynić z tego metodę czy właściwość?

Przyjmę odpowiedź, która jest najbardziej ogólna i wyczerpująca, ale dotyczy również podanego przeze mnie przykładu.

Trumpi
źródło
2
-1 to pytanie zostało zadane i udzielono na nie odpowiedzi wcześniej: stackoverflow.com/questions/164527/…
Element
Zalety i wady metody / dziedziny / własności mogą generować długie debaty; ogólne zastosowanie właściwości: gdy chcesz mieć pola prywatne / chronione, ale jednocześnie chcesz je ujawnić. Innym zastosowaniem jest nie tylko instrukcje, ale także wyrażenia (akcje, jeśli chcesz), a nawet if()kontrole (zgodnie z MSDN). Jest to jednak trudne, ponieważ użytkownik nie zawsze jest świadomy kosztu przetwarzania związanego z dostępem do zmiennej (właściwości) (tj. Kod nie jest dostępny) i ze względów ścisłych należałoby porównać tę właściwość. Aha, i "bonus", którego nie można używać wskaźników z właściwościami.
mireazma

Odpowiedzi:

145

Z sekcji Wybór między właściwościami a metodami w Wytycznych projektowych dotyczących tworzenia bibliotek klas:

Ogólnie metody reprezentują akcje, a właściwości reprezentują dane. Właściwości mają być używane jak pola, co oznacza, że ​​właściwości nie powinny być obliczeniowo złożone ani powodować skutków ubocznych. Jeśli nie narusza to poniższych wskazówek, rozważ użycie właściwości, a nie metody, ponieważ mniej doświadczeni programiści uważają, że właściwości są łatwiejsze w użyciu.

Ken Browning
źródło
3
Chociaż w większości się z tym zgadzam, nie sądzę, żeby część dotycząca skutków ubocznych była właściwa. Na przykład „Kolor” jest często właściwością obiektu i ma oczywiste skutki uboczne (zmiana koloru obiektu). Zmiana właściwości ma oczywisty efekt uboczny zmiany stanu obiektu.
Erik Funkenbusch
46
Mystere Man zmiana koloru jest efektem pożądanym, a nie efektem ubocznym. Efekt uboczny to coś, co nie jest przeznaczone w podstawowym działaniu.
Muhammad Hasan Khan
2
@Mystere Man: zdecydowanie zmiana koloru nie jest efektem ubocznym, całkowicie zgadzam się z tą odpowiedzią
Ahmed powiedział
2
„Ponieważ mniej doświadczeni programiści uważają, że właściwości są łatwiejsze w użyciu”. - Jak widzę, to jedyny powód, aby ujawniać właściwości. Ale czy mam rację?
Tsabo
2
Jaka jest różnica między wewnętrzną implementacją właściwości a metodą. Czy cokolwiek jest umieszczane na stosie wywołań za każdym razem, gdy używana jest właściwość? Jeśli nie, jak inaczej jest obsługiwany?
Praveen
57

Tak, jeśli wszystko, co robisz, to pobieranie i ustawianie, użyj właściwości.

Jeśli robisz coś złożonego, co może mieć wpływ na kilka członków danych, metoda jest bardziej odpowiednia. Lub jeśli twój getter przyjmuje parametry lub twój setter zajmuje więcej niż parametr wartości.

Pośrodku znajduje się szary obszar, na którym linia może być lekko rozmyta. Nie ma twardej i szybkiej reguły, a różni ludzie czasami nie zgadzają się, czy coś powinno być własnością, czy metodą. Ważne jest, aby być (względnie) spójnym z tym , jak to robisz (lub jak robi to twój zespół).

Są one w większości wymienne, ale właściwość sygnalizuje użytkownikowi, że implementacja jest stosunkowo „prosta”. Aha, a składnia jest trochę czystsza.

Mówiąc ogólnie, moja filozofia jest taka, że ​​jeśli zaczniesz pisać nazwę metody, która zaczyna się od get lub set i przyjmuje odpowiednio zero lub jeden parametr, to jest to główny kandydat na właściwość.

cletus
źródło
1
Głosowano w dół. To nie jest poprawne. Złożoność metody pobierającej lub ustawiającej jest zawarta w kodzie pobierającym / ustawiającym. Jak bardzo złożona jest w ogóle, nie ma znaczenia, ani jeśli „wpływa na kilka elementów danych”. Prawdą jest, że niestandardowe lub wielokrotne parametry będą wymagały metody, ale poza tym ta odpowiedź nie jest dokładna.
Hal50000
Pierwsze zdanie wyjaśnia wszystko. Brawo.
SWIIWII
13

Właściwości to sposób wstrzykiwania lub pobierania danych z obiektu. Tworzą abstrakcję dla zmiennych lub danych w klasie. Są analogiczne do metod pobierających i ustawiających w Javie.

Metody hermetyzują operację.

Ogólnie rzecz biorąc, używam właściwości do ujawniania pojedynczych bitów danych lub małych obliczeń dotyczących klasy, takich jak podatek od sprzedaży. Który jest określany na podstawie liczby przedmiotów i ich kosztu w koszyku.

Podczas tworzenia operacji używam metod, takich jak pobieranie danych z bazy danych. Każda operacja, która ma ruchome części, jest kandydatem do metody.

W twoim przykładzie kodu zawinąłbym go we właściwości, jeśli potrzebuję uzyskać do niego dostęp poza klasą zawierającą:

public Label Title 
{
   get{ return titleLabel;}
   set{ titleLabel = value;}
}

Ustawienie tekstu:

Title.Text = "Properties vs Methods";

Gdybym tylko ustawiał właściwość Text etykiety, tak bym to zrobił:

public string Title 
{
   get{ return titleLabel.Text;}
   set{ titleLabel.Text = value;}
}

Ustawienie tekstu:

Title = "Properties vs Methods";
Chuck Conway
źródło
12

Jeśli ustawiasz rzeczywistą właściwość swojego obiektu, używasz właściwości.

Jeśli wykonujesz zadanie / funkcję, używasz metody.

W twoim przykładzie jest to ustawiana określona właściwość.

Jeśli jednak twoja funkcjonalność byłaby AppendToLabel, użyłbyś metody.

Robin Day
źródło
11

Przeszukując MSDN, znalazłem odniesienie do właściwości a metody, które zawiera kilka świetnych wskazówek dotyczących tworzenia metod:

  • Operacja jest konwersją, na przykład Object.ToString .
  • Operacja jest na tyle kosztowna, że ​​chcesz poinformować użytkownika, że ​​powinien rozważyć zapisanie wyniku w pamięci podręcznej.
  • Uzyskanie wartości właściwości za pomocą metody dostępu get miałoby zauważalny efekt uboczny.
  • Dzwonienie do członka dwa razy z rzędu daje różne rezultaty.
  • Kolejność wykonania jest ważna. Należy pamiętać, że właściwości typu powinny mieć możliwość ustawiania i pobierania w dowolnej kolejności.
  • Element członkowski jest statyczny, ale zwraca wartość, którą można zmienić.
  • Element członkowski zwraca tablicę. Właściwości zwracające tablice mogą być bardzo mylące. Zwykle konieczne jest zwrócenie kopii tablicy wewnętrznej, aby użytkownik nie mógł zmienić stanu wewnętrznego. To, w połączeniu z faktem, że użytkownik może łatwo założyć, że jest to właściwość indeksowana, prowadzi do nieefektywnego kodu.
Gavin Miller
źródło
Zgadzam się, że ma to sens wszędzie tam, gdzie ma to zastosowanie. Ale czy mam rację, że użycie właściwości za pośrednictwem powiązania XAML w WPF nie pozostawia innego wyboru niż wykonanie odpowiednich działań w metodzie ustawiającej? (szczególnie w przypadku nowego SelectedItem dla ComboBoxes, ListBoxes itp.)
Nicolas
9

Wystarczy spojrzeć na samą nazwę ... „Nieruchomość”. Co to znaczy? Słownik definiuje to na wiele sposobów, ale w tym przypadku „zasadniczy lub wyróżniający atrybut lub jakość rzeczy” pasuje najlepiej.

Pomyśl o celu działania. Czy faktycznie zmieniasz lub odzyskujesz „istotny lub wyróżniający atrybut”? W swoim przykładzie używasz funkcji do ustawiania właściwości pola tekstowego. To wydaje się trochę głupie, prawda?

Właściwości naprawdę są funkcjami. Wszystkie kompilują się do getXXX () i setXXX (). Po prostu ukrywa je w cukrze syntaktycznym, ale to cukier nadaje temu procesowi znaczenie semantyczne.

Pomyśl o właściwościach, takich jak atrybuty. Samochód ma wiele cech. Kolor, MPG, Model itp. Nie wszystkie właściwości można ustawić, niektóre można obliczyć.

Tymczasem metoda to działanie. GetColor powinna być właściwością. GetFile () powinna być funkcją. Inną praktyczną zasadą jest to, że jeśli nie zmienia stanu obiektu, to powinna być funkcją. Na przykład CalculatePiToNthDigit (n) powinna być funkcją, ponieważ w rzeczywistości nie zmienia stanu obiektu Math, do którego jest dołączony.

To może być trochę rozwlekłe, ale tak naprawdę sprowadza się do podjęcia decyzji, jakie są twoje obiekty i co one reprezentują. Jeśli nie możesz dowiedzieć się, czy powinna to być właściwość czy funkcja, może nie ma znaczenia, która.

Erik Funkenbusch
źródło
9

Symantycznie właściwości są atrybutami twoich obiektów. Metody to zachowania twojego obiektu.

Etykieta jest atrybutem i bardziej sensowne jest nadanie jej właściwości.

Jeśli chodzi o programowanie obiektowe, powinieneś mieć jasne zrozumienie, co jest częścią zachowania, a co jest tylko atrybutem.

Samochód {kolor, model, marka}

Samochód ma atrybuty Color, Model i Brand, dlatego nie ma sensu mieć metody SetColor lub SetModel, ponieważ symetrycznie nie prosimy Cara o ustawienie własnego koloru.

Więc jeśli przypiszesz przypadek własności / metody do obiektu z prawdziwego życia lub spojrzysz na to z symantycznego punktu widzenia, twoje zamieszanie naprawdę zniknie.

Muhammad Hasan Khan
źródło
4

Dużym plusem właściwości jest również to, że wartość właściwości można zobaczyć w programie Visual Studio podczas debugowania.

David Karlaš
źródło
3

Wolę używać właściwości do dodawania / ustawiania metod z 1 parametrem. Jeśli parametrów jest więcej, użyj metod.

abatishchev
źródło
3

Właściwości powinny być tylko proste ustawić i uzyskać jedną wkładkę. Coś więcej i naprawdę należy to przenieść do metody. Złożony kod powinien zawsze znajdować się w metodach.

Neil Bostrom
źródło
3

Używam właściwości tylko do dostępu do zmiennych, tj. Pobierania i ustawiania poszczególnych zmiennych lub pobierania i ustawiania danych w kontrolkach. Gdy tylko jest potrzebna / wykonana jakakolwiek manipulacja danymi, używam metod.

Marcus L.
źródło
3

Z punktu widzenia projektu Właściwości reprezentują dane lub atrybuty obiektu klasy, podczas gdy metody są działaniami lub zachowaniami obiektu klasy.

W .Net świecie istnieją inne konsekwencje używania właściwości:

  • Właściwości są używane w wiązaniu danych, podczas gdy metody get_ / set_ nie.
  • Właściwości użytkownika serializacji XML jako naturalny mechanizm serilizacji.
  • Dostęp do właściwości uzyskuje się za pomocą formantu PropertyGrid i wewnętrznego ICustomTypeDescriptor , które mogą być skutecznie używane, jeśli piszesz bibliotekę niestandardową.
  • Właściwości są kontrolowane przez Atrybuty , można ich mądrze używać do projektowania oprogramowania zorientowanego na aspekt.

Błędne przekonania (IMHO) na temat użytkowania właściwości:

  • Służy do ujawniania małych obliczeń: blok get ControlDesigner.SelectionRules zajmuje 72 linie !!
  • Służy do ujawniania wewnętrznych struktur danych: nawet jeśli właściwość nie jest mapowana na wewnętrzny element członkowski danych, można jej użyć jako właściwości, jeśli jest to atrybut Twojej klasy. Viceversa, nawet jeśli jest to atrybut właściwości twojej klasy, nie jest zalecany, aby zwracać tablicę, taką jak składowe danych (zamiast tego metody są używane do zwracania głębokiej kopii elementów członkowskich).

W poniższym przykładzie można to zapisać, mając większe znaczenie biznesowe jako:

public String Title
{
    set { Label.Text = text; }
}
NileshChauhan
źródło
2

Właściwości są naprawdę ładne, ponieważ są dostępne w projektancie wizualnym studia wizualnego, pod warunkiem, że mają do nich dostęp.

Używa się ich tam, gdzie po prostu ustawiasz i pobierasz, a być może jakąś walidację, która nie ma dostępu do znacznej ilości kodu. Uważaj, ponieważ tworzenie złożonych obiektów podczas walidacji nie jest proste.

Cokolwiek innego jest preferowanym sposobem.

Nie chodzi tylko o semantykę. Używanie niewłaściwych właściwości zaczyna mieć dziwne skutki w projektancie wizualnym studia wizualnego.

Na przykład otrzymywałem wartość konfiguracji w ramach właściwości klasy. Klasa konfiguracyjna w rzeczywistości otwiera plik i wykonuje zapytanie sql, aby uzyskać wartość tej konfiguracji. Spowodowało to problemy w mojej aplikacji, w której plik konfiguracyjny był otwierany i blokowany przez samo Visual Studio, a nie przez moją aplikację, ponieważ nie tylko odczytywał, ale zapisywał wartość konfiguracyjną (za pomocą metody ustawiającej). Aby to naprawić, musiałem po prostu zmienić to na metodę.

Jeremy Edwards
źródło
1

Oto dobry zestaw wskazówek, kiedy należy używać właściwości, a kiedy metod od Billa Wagnera

  • Użyj Property, gdy wszystkie te wartości są prawdziwe: metody pobierające powinny być proste i dlatego prawdopodobnie nie będą generować wyjątków. Należy zauważyć, że oznacza to brak dostępu do sieci (lub bazy danych). Albo może się nie powieść, a zatem zgłosi wyjątek.
  • Nie powinny mieć wzajemnych zależności. Zauważ, że obejmowałoby to ustawienie jednej właściwości i wpłynięcie jej na inną. (Na przykład ustawienie właściwości FirstName wpłynęłoby na właściwość FullName tylko do odczytu, która składa się z właściwości imienia + nazwiska, implikuje taką zależność)
  • Powinny być możliwe do ustawienia w dowolnej kolejności
  • Metoda pobierająca nie ma obserwowalnego efektu ubocznego Zauważ, że ta wskazówka nie wyklucza niektórych form leniwego szacowania właściwości.
  • Metoda musi zawsze zwracać się natychmiast. (Należy pamiętać, że wyklucza to właściwość, która powoduje wywołanie dostępu do bazy danych, wywołanie usługi sieci Web lub inną podobną operację).
  • Użyj metody, jeśli element członkowski zwraca tablicę.
  • Powtarzające się wywołania metody pobierającej (bez kodu pośredniczącego) powinny zwracać tę samą wartość.
  • Powtarzające się wywołania metody ustawiającej (o tej samej wartości) nie powinny przynosić żadnej różnicy w porównaniu z pojedynczym wywołaniem.

  • Get nie powinien zwracać odniesienia do wewnętrznych struktur danych (patrz punkt 23). Metoda może zwrócić głęboką kopię i uniknąć tego problemu.

* Zaczerpnięte z mojej odpowiedzi na zduplikowane pytanie.

Chris Ballance
źródło
Najwyżej oceniane i akceptowane odpowiedzi tutaj stackoverflow.com/a/1294189/1551 Dlaczego głosowanie przeciw?
Chris Ballance,
2
Zdaję sobie sprawę, że trochę się spóźniłem na imprezę, ale ta negatywna opinia najprawdopodobniej wynikła z faktu, że skopiowałeś swoją odpowiedź. Przez wklejanie kopii przyznałeś, że to pytanie było w zasadzie duplikatem drugiego. W związku z tym, zamiast odpowiadać, powinieneś był oznaczyć go jako duplikat. Polecam zapoznać się z artykułem na Meta, aby dowiedzieć się, jak radzić sobie z podwójnymi pytaniami.
Joshua,
0

To jest proste.

1: użyj właściwości, jeśli chcesz, aby Twoje dane zostały zweryfikowane przed zapisaniem w polu. W ten sposób właściwość zapewnia hermetyzację pól. Ponieważ jeśli opuścisz swoje pola, publiczny użytkownik końcowy może przypisać dowolną wartość, która może być ważna lub nie, zgodnie z wymaganiami biznesowymi, na przykład wiek powinien być większy niż 18. Więc zanim wartość zostanie zapisana w odpowiednim polu, musimy sprawdzić jego ważność. W ten sposób właściwości reprezentują dane.

2: Użyj metody, gdy chcesz wykonać jakąś akcję, taką jak podawanie pewnych danych jako parametru, a twoja metoda wykonuje pewne przetwarzanie na podstawie dostarczonych wartości i zwraca przetworzoną wartość jako wyjście. Lub chcesz zmienić wartość jakiegoś pola za pomocą tego obliczenia. „W ten sposób metoda reprezentuje działanie”.

Marsjanin
źródło
-1

Pochodzę z javy i przez jakiś czas używałem metody get .. set ...

Kiedy piszę kod, nie pytam siebie: „dostęp do tych danych jest prosty czy wymaga skomplikowanego procesu?” ponieważ rzeczy mogą się zmienić (dziś odzyskanie tej właściwości jest proste, jutro może wymagać pewnego lub ciężkiego procesu).

Dzisiaj mam metodę SetAge (int wiek) jutro. Będę miała również metodę SetAge (data urodzenia), która oblicza wiek na podstawie daty urodzenia.

Byłem bardzo rozczarowany, że właściwość transform kompilatora w get i set, ale nie traktuj moich metod Get ... i Set .. jako takich samych.

Marco Staffoli
źródło