Czy są jakieś powody, aby używać własności prywatnych W C#?
Właśnie zdałem sobie sprawę, że konstrukcja właściwości C# może być również używana z modyfikatorem dostępu private :
private string Password { get; set; }
Chociaż jest to technicznie interesujące, nie wyobrażam sobie, kiedy bym go użył, ponieważ prywatne pole obejmuje nawet mniej ceremonii :
private string _password;
I nie wyobrażam sobie, kiedy kiedykolwiek będę musiała być w stanie get but not set lub set but not get prywatny pole:
private string Password { get; }
Lub
private string Password { set; }
Ale być może istnieje przypadek użycia z zagnieżdżonymi / dziedziczonymi klasami lub być może get/set może zawierać logikę zamiast po prostu zwracać wartość właściwości, chociaż chciałbym zachować właściwości ściśle proste i pozwolić jawnym metodom wykonywać dowolną logikę, np. GetEncodedPassword()
.
Czy ktoś używa prywatnych właściwości w C# z jakiegokolwiek powodu, czy jest to tylko jedna z tych technicznie-możliwych-ale-rzadko-używanych-w-rzeczywistym-kodzie konstrukcje?
Dodatek
Ładne odpowiedzi, czytając je opisałem te zastosowania dla własności prywatnych:
- gdy pola prywatne muszą być leniwie ładowane
- gdy pola prywatne wymagają dodatkowej logiki lub są wartościami obliczonymi
- ponieważ debugowanie prywatnych pól może być trudne]} W celu "zaprezentowania sobie umowy"]} W ten sposób można łatwo przekształcić i uprościć obiekt jako część serializacji.]}
- owijanie zmienne globalne do użycia wewnątrz klasy
14 answers
Używam ich, jeśli muszę buforować wartość i chcę ją leniwie załadować.
private string _password;
private string Password
{
get
{
if (_password == null)
{
_password = CallExpensiveOperation();
}
return _password;
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-06 20:12:38
Podstawowym zastosowaniem tego w moim kodzie jest leniwa inicjalizacja, jak już inni wspominali.
Innym powodem, dla którego prywatne właściwości są nad polami, jest to, że prywatne właściwości są dużo, dużo łatwiejsze do debugowania niż prywatne pola. Często chcę wiedzieć rzeczy takie jak " to pole jest ustawiane nieoczekiwanie; kto jest pierwszym wywołującym, który ustawia to pole?"jest to o wiele łatwiejsze, jeśli możesz po prostu umieścić punkt przerwania na seterze i nacisnąć go. Możesz tam umieścić logowanie. Możesz umieścić wydajność tam są metryki. Możesz wprowadzić kontrole spójności, które są uruchamiane w kompilacji debugowania.
Zasadniczo sprowadza się to do: kod jest znacznie potężniejszy niż DANE . Każda technika, która pozwala mi napisać kod, którego potrzebuję, jest dobra. Pola nie pozwalają na pisanie w nich kodu, właściwości tak.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-22 15:16:34
Być może istnieje przypadek użycia z klasami zagnieżdżonymi / dziedziczonymi lub być może get / set może zawierać logikę zamiast zwracać wartość właściwości
Osobiście używam tego nawet wtedy, gdy nie potrzebuję logiki na getterze lub setterze właściwości. Korzystanie z właściwości, nawet prywatnej, pomaga zabezpieczyć kod w przyszłości, dzięki czemu można dodać logikę do gettera później, jeśli jest to wymagane.
Jeśli uznam, że nieruchomość może w końcu wymagać dodatkowej logiki, będę czasami zawinąć go do prywatnej własności, zamiast używać pola, tylko po to, żebym nie musiał zmieniać kodu później.
W częściowo powiązanym przypadku (choć innym niż twoje pytanie), bardzo często używam prywatnych seterów na publicznych właściwościach:
public string Password
{
get;
private set;
}
To daje Ci publiczny getter, ale utrzymuje setera w tajemnicy.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-22 14:56:05
Leniwa inicjalizacja to jedno miejsce, w którym mogą być schludne, np.
private Lazy<MyType> mytype = new Lazy<MyType>(/* expensive factory function */);
private MyType MyType { get { return this.mytype.Value; } }
// In C#6, you replace the last line with: private MyType MyType => myType.Value;
Wtedy możesz napisać: this.MyType
wszędzie, a nie this.mytype.Value
i zawrzeć fakt, że jest on leniwie utworzony w jednym miejscu.
Jedna rzecz, która jest wstydliwa, to to, że C# nie obsługuje przeszukiwania pola zaplecza do właściwości (tj. deklarowania go wewnątrz definicji właściwości), aby całkowicie ją ukryć i upewnić się, że może być dostępna tylko za pośrednictwem właściwości.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-03 18:39:27
Jednym z dobrych zastosowań dla prywatnych właściwości get only są obliczane wartości. Kilka razy miałem właściwości, które są prywatne readonly i po prostu zrobić obliczenia nad innymi polami w moim typie. To nie jest godne metody i nie interesujące dla innych klas, więc własność prywatna to jest.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-22 15:06:12
Jedyne użycie, o którym myślę
private bool IsPasswordSet
{
get
{
return !String.IsNullOrEmpty(_password);
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-22 14:59:50
Właściwości i pola nie są pojedynczo. Właściwość dotyczy interfejsu klasy (niezależnie od tego, czy chodzi o jej publiczny czy wewnętrzny Interfejs), podczas gdy pole dotyczy implementacji klasy. Właściwości nie powinny być postrzegane jako sposób na wyeksponowanie pól, powinny być postrzegane jako sposób na wyeksponowanie intencji i celu klasy.
Tak jak używasz właściwości, aby przedstawić konsumentom umowę na to, co stanowi Twoją klasę, możesz również przedstawić umowę na siebie z bardzo podobnych powodów. Więc tak, używam prywatnych nieruchomości, gdy ma to sens. Czasami własność prywatna może ukryć szczegóły implementacji, takie jak leniwe Ładowanie, fakt, że właściwość jest naprawdę konglomeratem kilku pól i aspektów lub że właściwość musi być wirtualnie utworzona przy każdym wywołaniu (think DateTime.Now
). Są zdecydowanie momenty, w których sensowne jest egzekwowanie tego nawet na sobie w zapleczu klasy.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-22 15:01:45
Używam ich w serializacji, z rzeczami takimi jak DataContractSerializer
lub protobuf-net, które obsługują to użycie (XmlSerializer
nie). Jest to przydatne, jeśli trzeba uprościć obiekt w ramach serializacji:
public SomeComplexType SomeProp { get;set;}
[DataMember(Order=1)]
private int SomePropProxy {
get { return SomeProp.ToInt32(); }
set { SomeProp = SomeComplexType.FromInt32(value); }
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-22 15:29:10
Jedną rzeczą, którą robię cały czas, jest przechowywanie "globalnych" zmiennych / pamięci podręcznej w HttpContext.Current
private static string SomeValue{
get{
if(HttpContext.Current.Items["MyClass:SomeValue"]==null){
HttpContext.Current.Items["MyClass:SomeValue"]="";
}
return HttpContext.Current.Items["MyClass:SomeValue"];
}
set{
HttpContext.Current.Items["MyClass:SomeValue"]=value;
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-22 15:37:18
Używam ich od czasu do czasu. Mogą one ułatwić debugowanie rzeczy, gdy można łatwo umieścić w punkcie przerwania we właściwości lub można dodać instrukcję logging itp.
Może być również przydatny, jeśli później trzeba zmienić rodzaj danych w jakiś sposób lub jeśli trzeba użyć refleksji.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-22 14:55:31
Używam prywatnych właściwości, aby zmniejszyć kod dostępu do sub właściwości, które często są używane.
private double MonitorResolution
{
get { return this.Computer.Accesories.Monitor.Settings.Resolution; }
}
Jest to przydatne, jeśli istnieje wiele właściwości podrzędnych.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-03 10:25:23
Powszechną praktyką jest modyfikowanie tylko członków za pomocą metod get/set, nawet prywatnych. Logika jest taka, że Twój get / set zawsze zachowuje się w określony sposób (na przykład odpalanie zdarzeń), co nie wydaje się mieć sensu, ponieważ nie będą one zawarte w schemacie właściwości... ale stare nawyki umierają ciężko.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-22 14:57:17
Ma to sens, gdy z właściwością set lub get jest powiązana logika (think lazy initialization) i właściwość jest używana w kilku miejscach w klasie.
Jeśli to tylko proste pole zapasowe? Nic nie przychodzi mi do głowy jako dobry powód.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-22 14:58:15
Cóż, jak nikt nie wspomniał, można go użyć do walidacji danych lub do blokowania zmiennych.
-
Walidacja
string _password; string Password { get { return _password; } set { // Validation logic. if (value.Length < 8) { throw new Exception("Password too short!"); } _password = value; } }
-
Blokowanie
object _lock = new object(); object _lockedReference; object LockedReference { get { lock (_lock) { return _lockedReference; } } set { lock (_lock) { _lockedReference = value; } } }
Uwaga: podczas blokowania odniesienia nie blokuje się dostępu do elementów obiektu odniesienia.
Lazy reference: gdy leniwe ładowanie może skończyć się koniecznością zrobienia tego asynchronicznego, dla którego obecnie istnieje AsyncLazy . Jeśli korzystasz ze starszych wersji niż Visual Studio SDK 2015 lub nie używając go Możesz również użyć asynclazy AsyncEx.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-25 01:59:52