In welcher Situation sollte ich ein privates Set für eine Eigenschaft verwenden, anstatt es zu einer ReadOnly-Eigenschaft zu machen? Berücksichtigen Sie die beiden folgenden sehr simplen Beispiele.
Erstes Beispiel:
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);
}
}
Zweites Beispiel:
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);
}
}
Sie liefern beide die gleichen Ergebnisse. Ist dies eine Situation, in der es kein Richtig und Falsch gibt und es nur eine Frage der Präferenz ist?
public string Name { get; protected set; }
durch Vererbung.Antworten:
Es gibt ein paar Gründe, um zu verwenden
private set
.1) Wenn Sie überhaupt kein Hintergrundfeld verwenden und eine schreibgeschützte automatische Eigenschaft wünschen:
2) Wenn Sie zusätzliche Arbeit leisten möchten, wenn Sie die Variable in Ihrer Klasse ändern und diese an einem einzigen Ort erfassen möchten:
Im Allgemeinen ist es jedoch eine Frage der persönlichen Präferenz. Soweit ich weiß, gibt es keine Leistungsgründe, um eine übereinander zu verwenden.
quelle
private set
. :-)public string Name { get; }
. Wenn Sie keine veränderbare Eigenschaft möchten, ist dies jetzt die bevorzugte Syntax.private set
ist, dass es nicht so unveränderlich ist, wie wir es gerne vortäuschen. Wenn Sie eine wirklich unveränderliche Klasse implementieren möchten, ist schreibgeschützt ein Muss.Verwenden Sie Private Set, wenn Sie möchten, dass Setter nicht von außen zugänglich sind .
Verwenden Sie readonly, wenn Sie die Eigenschaft nur einmal festlegen möchten . Im Konstruktor oder Variableninitialisierer.
TESTEN SIE DIESES:
quelle
readonly
-Schlüsselwort giltReadOnly
für das Feld und nicht für die Eigenschaft.Darf ich eine dritte Option vorschlagen?
Dadurch ist die Name-Eigenschaft für den gesamten externen Code schreibgeschützt und es wird eine explizite Set-Methode bereitgestellt. Ich bevorzuge das explizite Set, anstatt einfach das Set für die Name-Eigenschaft zu verwenden, da Sie den Wert beim Festlegen ändern. Wenn Sie einen Eigenschaftswert festlegen , erwarten Sie normalerweise, dass Sie denselben Wert zurückerhalten , wenn Sie den Befehl get später aufrufen . Dies würde nicht passieren, wenn Sie ToTitleCase im Set ausführen würden .
Wie Sie sagten, gibt es jedoch keine richtige Antwort.
quelle
Ab C # 6.0 wurden der Sprache automatische Getter-Eigenschaften hinzugefügt. Siehe hier: https://github.com/dotnet/roslyn/wiki/New-Language-Features-in-C%23-6#getter-only-auto-properties .
Hier ist ein Beispiel:
quelle
Verwenden Sie nicht das zweite Beispiel. Der springende Punkt bei der Verwendung einer Eigenschaft ist, den gesamten Zugriff durch diesen Getter und Setter zu leiten, auch wenn nichts anderes als der Getter-Vorgang und die Setter-Einstellung ausgeführt werden ein Platz.
In Ihrem zweiten Beispiel wird dies beim Festlegen der Eigenschaft aufgegeben. Wenn Sie diesen Ansatz in einer großen, komplexen Klasse verwendet haben und später das Verhalten der Eigenschaft ändern müssen, befinden Sie sich im Land der Suche und Ersetzung, anstatt die Änderung an einem Ort vorzunehmen - dem privaten Setter.
quelle
Wann immer ich die Zugriffsebene eines Setters ändern musste, habe ich sie im Allgemeinen in "Geschützt" (nur diese Klasse und abgeleitete Klassen können den Wert ändern) oder "Freund" (nur Mitglieder meiner Assembly können den Wert ändern) geändert.
Die Verwendung von "Privat" ist jedoch sinnvoll, wenn Sie neben dem Ändern des Sicherungswerts noch andere Aufgaben im Setter ausführen möchten. Wie bereits erwähnt, empfiehlt es sich, nicht direkt auf Ihre Hintergrundwerte zu verweisen, sondern nur über deren Eigenschaften darauf zuzugreifen. Dadurch wird sichergestellt, dass spätere Änderungen, die Sie an einer Eigenschaft vornehmen, sowohl intern als auch extern angewendet werden. Und es gibt praktisch keine Leistungseinbußen beim Verweisen auf eine Eigenschaft im Vergleich zu ihrer Sicherungsvariablen.
quelle
Der Zugriff auf eine Eigenschaft ist jedoch langsamer als der Zugriff auf die Sicherungsvariable. Getter und Setter einer Eigenschaft sind Methoden, die einen Call und einen Return erfordern, während auf die Backing-Variable einer Eigenschaft direkt zugegriffen wird.
Aus diesem Grund wird in Fällen, in denen auf den Getter einer Eigenschaft innerhalb eines Codeblocks häufig zugegriffen werden kann, der Wert der Eigenschaft manchmal zuerst zwischengespeichert (in einer lokalen Variablen gespeichert) und stattdessen die lokale Variable verwendet. Dies setzt natürlich voraus, dass die Eigenschaft nicht asynchron geändert werden kann, während der Block ausgeführt wird.
quelle