W jakiej sytuacji powinienem użyć prywatnego zestawu właściwości, a nie uczynić z niej własność tylko do odczytu? Weź pod uwagę dwa bardzo uproszczone przykłady poniżej.
Pierwszy przykład:
Public Class Person
Private _name As String
Public Property Name As String
Get
Return _name
End Get
Private Set(ByVal value As String)
_name = value
End Set
End Property
Public Sub WorkOnName()
Dim txtInfo As TextInfo = _
Threading.Thread.CurrentThread.CurrentCulture.TextInfo
Me.Name = txtInfo.ToTitleCase(Me.Name)
End Sub
End Class
// ----------
public class Person
{
private string _name;
public string Name
{
get { return _name; }
private set { _name = value; }
}
public void WorkOnName()
{
TextInfo txtInfo = System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo;
this.Name = txtInfo.ToTitleCase(this.Name);
}
}
Drugi przykład:
Public Class AnotherPerson
Private _name As String
Public ReadOnly Property Name As String
Get
Return _name
End Get
End Property
Public Sub WorkOnName()
Dim txtInfo As TextInfo = _
Threading.Thread.CurrentThread.CurrentCulture.TextInfo
_name = txtInfo.ToTitleCase(_name)
End Sub
End Class
// ---------------
public class AnotherPerson
{
private string _name;
public string Name
{
get { return _name; }
}
public void WorkOnName()
{
TextInfo txtInfo = System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo;
_name = txtInfo.ToTitleCase(_name);
}
}
Oba dają takie same wyniki. Czy jest to sytuacja, w której nie ma dobra i zła, a to tylko kwestia preferencji?
public string Name { get; protected set; }
poprzez dziedziczenie.Odpowiedzi:
Istnieje kilka powodów, dla których warto skorzystać
private set
.1) Jeśli w ogóle nie używasz pola kopii zapasowej i chcesz właściwości automatycznej tylko do odczytu:
2) Jeśli chcesz wykonać dodatkową pracę, gdy modyfikujesz zmienną w swojej klasie i chcesz uchwycić ją w jednym miejscu:
Ogólnie rzecz biorąc, jest to kwestia osobistych preferencji. O ile mi wiadomo, nie ma powodów, by używać jednego nad drugim.
źródło
private set
. :-)public string Name { get; }
. Jeśli nie chcesz modyfikowalnej właściwości, jest to teraz preferowana składnia.private set
jest to, że nie jest tak niezmienne, jak lubimy udawać. Jeśli chcesz zaimplementować prawdziwie niezmienną klasę, tylko do odczytu jest koniecznością.Użyj prywatnego zestawu, jeśli chcesz, aby setter nie był dostępny z zewnątrz .
Używaj tylko do odczytu, jeśli chcesz ustawić właściwość tylko raz . W konstruktorze lub inicjalizatorze zmiennych.
TESTUJ TO:
źródło
readonly
słowu kluczowemu C # ma być stosowanaReadOnly
do pola zamiast do właściwości.Czy mogę zasugerować trzecią opcję?
To sprawia, że właściwość Name skutecznie tylko do odczytu dla całego kodu zewnętrznego i zapewnia jawną metodę Set. Wolę jawny zestaw niż zwykłe użycie zestawu we właściwości Name, ponieważ zmieniasz wartość podczas ustawiania. Zwykle, jeśli ustawisz wartość właściwości, spodziewaj się, że odzyskasz tę samą wartość, kiedy zadzwonisz do get później, co nie zdarzyłoby się, gdybyś wykonał ToTitleCase w zestawie .
Jednak, jak powiedziałeś, nie ma jednej właściwej odpowiedzi.
źródło
Począwszy od wersji C # 6.0, do języka dodano właściwości automatyczne tylko do gettera. Zobacz tutaj: https://github.com/dotnet/roslyn/wiki/New-Language-Features-in-C%23-6#getter-only-auto-properties .
Oto przykład:
źródło
Nie używaj drugiego przykładu. Cały sens korzystania z właściwości - nawet jeśli nie dzieje się nic poza pobieraniem gettera i ustawieniem setera - polega na przeprowadzeniu całego dostępu przez ten getter i seter, aby jeśli kiedykolwiek będziesz musiał zmienić zachowanie w przyszłości, wszystko jest w jedno miejsce.
Drugi przykład rezygnuje z tego w przypadku ustawiania właściwości. Jeśli zastosowałeś to podejście w dużej, złożonej klasie, a później musiałeś zmienić zachowanie nieruchomości, byłbyś w obszarze wyszukiwania i zamiany gruntów, zamiast zmiany w jednym miejscu - prywatnym seterze.
źródło
Ilekroć musiałem zmieniać poziom dostępu ustawiacza, generalnie zmieniałem go na Chroniony (tylko ta klasa i klasy pochodne mogą zmieniać wartość) lub Przyjaciel (tylko członkowie mojego zestawu mogą zmieniać wartość).
Ale korzystanie z trybu prywatnego ma sens, gdy chcesz wykonywać inne zadania w seterie oprócz zmiany wartości kopii zapasowej. Jak wskazano wcześniej, dobrym pomysłem jest, aby nie odwoływać się bezpośrednio do wartości kopii zapasowej, ale zamiast tego uzyskiwać do nich dostęp tylko poprzez ich właściwości. To gwarantuje, że późniejsze zmiany, które wprowadzisz we właściwości, zostaną zastosowane zarówno wewnętrznie, jak i zewnętrznie. Odwołanie do właściwości vs jej zmiennej bazowej praktycznie nie ma negatywnego wpływu na wydajność.
źródło
Ale dla wyjaśnienia dostęp do właściwości jest wolniejszy niż dostęp do jej zmiennej pomocniczej. Moduł pobierający i ustawiający właściwości są metodami, które wymagają wywołania i zwrotu, natomiast zmienna pomocnicza właściwości jest dostępna bezpośrednio.
Dlatego w przypadkach, gdy do gettera właściwości można uzyskać wiele razy w bloku kodu, wartość właściwości jest czasami najpierw buforowana (zapisywana w zmiennej lokalnej) i zamiast niej używana jest zmienna lokalna. Oczywiście przy założeniu, że właściwości nie można zmienić asynchronicznie podczas wykonywania bloku.
źródło