Zrobiłbym krok dalej i przedstawiłbym 3 przypadki. Mimo że są różne dla każdego, to są reguły, których używam przez większość czasu podczas programowania w C #.
W przypadku 2 i 3 zawsze idź do Accessor Accessor (nie zmienna pola). W przypadku 1 jesteś uratowany nawet przed koniecznością dokonania tego wyboru.
1.) Nieruchomość niezmienna (przekazana konstruktorowi lub utworzona w czasie budowy). W tym przypadku używam zmiennej pola z właściwością tylko do odczytu. Wybieram to w stosunku do prywatnego setera, ponieważ prywatny seter nie gwarantuje niezmienności.
public class Abc
{
private readonly int foo;
public Abc(int fooToUse){
foo = fooToUse;
}
public int Foo { get{ return foo; } }
}
2.) Zmienna POCO. Prosta zmienna, która może uzyskać / ustawić w dowolnym zakresie publicznym / prywatnym. W takim przypadku użyłbym po prostu właściwości automatycznej.
public class Abc
{
public int Foo {get; set;}
}
3.) Właściwości wiązania ViewModel. Dla klas, które obsługują INotifyPropertyChanged, myślę, że potrzebujesz prywatnej zmiennej pola bazowego.
public class Abc : INotifyPropertyChanged
{
private int foo;
public int Foo
{
get { return foo; }
set { foo = value; OnPropertyChanged("foo"); }
}
}
public int Foo {get; set;}
zamiastpublic int Foo
?Ogólnie powiedziałbym, że przypisuj do pola w konstruktorze i używaj tej właściwości wszędzie indziej. W ten sposób, jeśli ktoś doda funkcjonalność do nieruchomości, nigdzie jej nie przegapisz.
Z pewnością nie jest to czynnik wydajności. Optymalizator wstawi dla Ciebie proste polecenie get lub set, a końcowy kod MSIL prawdopodobnie będzie identyczny.
źródło
Zależy.
Najpierw powinieneś preferować właściwości automatyczne, jeśli to możliwe:
Po drugie, lepszym podejściem byłoby prawdopodobnie użycie właściwości, jeśli masz jakąkolwiek logikę, prawdopodobnie powinieneś sam przez nią przejść, szczególnie jeśli ta logika jest synchronizacją wątków.
Ale powinieneś również wziąć pod uwagę, że może to nieco pogorszyć twoją wydajność, jeśli niepoprawnie synchronizujesz, możesz sam się zakleszczyć, a czasem właściwą ścieżką jest obejście logiki we właściwości.
źródło
public string MyValue {get; private set;}
.Najprościej byłoby po prostu przypisać ją do samej zmiennej, ponieważ jesteś w metodzie klasy i kontrolujesz zachowanie klasy.
Ale sedno własności polega na tym, że usuwają one zmienną. Podczas gdy taka prosta właściwość, jak w twoim przykładzie, nie ma żadnego zastosowania w stosunku do zwykłej publicznej zmiennej członka, właściwości zwykle robią (lub powinny robić) dodatkowe rzeczy w swoich obiektach pobierających i ustawiających. A jeśli chcesz, aby te rzeczy były wykonywane automatycznie podczas zmiany właściwości w klasie, to oczywiście czystsze jest działanie na właściwości zamiast zmiennej, aby nie musiała zmieniać każdego przypisania zmiennej, gdy zmienia się zachowanie ustawienia właściwości.
Musisz po prostu uzasadnić to koncepcyjnie. Właściwość jest w rzeczywistości uchwytem umożliwiającym dostęp do pewnego wewnętrznego stanu obiektu, który może składać się z więcej niż jednej zmiennej składowej. Musisz więc zadać sobie pytanie, czy chcesz zmienić tylko podstawowy stan wewnętrzny (lub tylko jego część), czy też właściwość abstrakcyjną reprezentującą ten stan w całości, a w większości przypadków jest to ten ostatni, ponieważ zwykle chcesz, aby Twój obiekt zawsze miał spójny stan.
źródło
Jeśli istnieje jakakolwiek szansa, że implementacja get / set właściwości zmieni się czasem później (na przykład chcesz wywołać zdarzenie podczas wywoływania
set
lub dodasz leniwy mechanizm oceny później do swojejget
funkcji), może to być dobry pomysł że twój kod wewnątrz klasy będzie używał tej właściwości w prawie wszystkich przypadkach, z wyjątkiem - najprawdopodobniej rzadkich - przypadków, w których wyraźnie nie chcesz, aby używane były te zdarzenia lub leniwe mechanizmy oceny.W każdym razie, cokolwiek zrobisz, istnieje duża szansa, że jeśli później zmienisz implementację właściwości w taki sposób, będziesz musiał spojrzeć na wszystkie miejsca w klasie, które uzyskują dostęp do tych właściwości, aby sprawdzić, czy naprawdę dostęp do właściwości lub należy zastosować zmienną prywatną.
źródło
Zawsze korzystam z własności publicznej.
Często do logiki dodawana jest pewna logika, która powinna zawsze działać, gdy właściwość jest ustawiona
set
, i zamiast tego ustawiając pole prywatne, ustawiacz publiczny omija tam dowolną logikę.Masz komentarz na temat MVVM prowadzący do tego pytania i uważam, że jest to jeszcze ważniejsze podczas pracy z MVVM. Wiele obiektów wywołuje
PropertyChange
powiadomienie ustawiające, a inne obiekty mogą zasubskrybować to zdarzenie, aby wykonać akcję po zmianie określonych właściwości. Jeśli ustawisz zmienną prywatną, akcje te nigdy się nie wykonają, chyba że ręcznie podniesieszPropertyChanged
zdarzenie.źródło
Zasadniczo od Ciebie zależy, co powinieneś zrobić z właściwością i jej polem zaplecza podczas pobierania / ustawiania.
Najczęściej, aby zachować spójność w całym kodzie, powinieneś używać publicznych akcesorów wszędzie tam, gdzie są one dostępne i odpowiednie. Pozwala to na refaktoryzację przy minimalnej zmianie kodu; jeśli metoda wykonująca to ustawienie musi zostać usunięta z klasy i umieszczona gdzie indziej, gdzie pole zaplecza nie jest już dostępne (jak klasa podstawowa), kogo to obchodzi? Używasz czegoś, co jest dostępne wszędzie tam, gdzie sama klasa ma wykonać zadanie. Pole zaplecza w większości przypadków stanowi szczegół implementacji; nikt poza twoją klasą nie powinien wiedzieć, że istnieje.
Główną sytuacją, o której mogę pomyśleć, kiedy powinieneś użyć pola zaplecza, a NIE akcesora właściwości, jest to, że akcesor ma dodatkową logikę (sprawdzanie poprawności lub aktualizację innych informacji o stanie w klasie), której nie chcesz uruchamiać. Przykładem jest początkowa populacja obiektu; możesz mieć klasę, która używa dwóch wartości właściwości do obliczenia trzeciej, która jest również przechowywana w polu kopii zapasowej (ze względu na trwałość). Podczas inicjowania nowej kopii tego obiektu podanej w bazie danych, akcesory właściwości, którzy ponownie obliczają trzecią wartość, mogą narzekać, jeśli druga potrzebna wartość nie jest ustawiona. Używając pól bazowych do ustawiania początkowych wartości tych dwóch (lub trzech) właściwości, omija się logikę sprawdzania poprawności / obliczeń, dopóki instancja nie będzie wystarczająco spójna, aby logika działała normalnie.
źródło
Zawsze używaj tego, który ma sens. Tak, wiem, że to brzmi dość fałszywie do tego stopnia, że nie ma odpowiedzi.
Istotą właściwości jest zapewnienie interfejsu, dzięki któremu można bezpiecznie uzyskać dostęp do modelu danych. W większości sytuacji zawsze chcesz bezpiecznie uzyskać dostęp do modelu danych za pośrednictwem tego interfejsu, na przykład:
Ale w innych sytuacjach możesz po prostu użyć właściwości jako widoku modelu danych:
Jeśli użycie radianów ma sens
SomeAngle
, to z całą pewnością skorzystaj z niego.Na koniec wypij swoją własną pomoc kool. Interfejs API dostępny publicznie powinien być wystarczająco odporny na pracę wewnętrzną.
źródło