Ich habe gerade festgestellt, dass das C # -Eigenschaftskonstrukt auch mit einem privaten Zugriffsmodifikator verwendet werden kann:
private string Password { get; set; }
Obwohl dies technisch interessant ist, kann ich mir nicht vorstellen, wann ich es verwenden würde, da ein privates Feld noch weniger Zeremonien beinhaltet :
private string _password;
und ich kann mir nicht vorstellen , wenn ich jemals fähig sein müssen , intern zu bekommen , aber nicht eingestellt oder Satz aber nicht bekommen ein eigenes Feld:
private string Password { get; }
oder
private string Password { set; }
aber vielleicht gibt es einen Anwendungsfall mit verschachtelten / geerbten Klassen oder vielleicht, wo ein get / set Logik enthalten könnte, anstatt nur den Wert der Eigenschaft zurückzugeben, obwohl ich dazu neigen würde, Eigenschaften streng einfach zu halten und explizite Methoden jede Logik ausführen zu lassen, zB GetEncodedPassword()
.
Verwendet jemand aus irgendeinem Grund private Eigenschaften in C # oder ist dies nur eines dieser technisch möglichen, aber selten im tatsächlichen Code verwendeten Konstrukte?
Nachtrag
Nette Antworten, durchlesen Ich habe diese Verwendungen für private Immobilien ausgesucht:
- wenn private Felder träge geladen werden müssen
- wenn private Felder zusätzliche Logik benötigen oder berechnete Werte sind
- da private Felder schwierig zu debuggen sein können
- um "sich selbst einen Vertrag vorzulegen"
- um eine exponierte Eigenschaft im Rahmen der Serialisierung intern zu konvertieren / zu vereinfachen
- Umschließen globaler Variablen, die in Ihrer Klasse verwendet werden sollen
quelle
Antworten:
Ich benutze sie, wenn ich einen Wert zwischenspeichern muss und ihn faul laden möchte.
quelle
return _password ?? (_password = CallExpensiveOperation());
return _password ?? (_password = CallExpensiveOperation());
. Oder Resharper bevorzugt es tatsächlich :).private string Password => _password ?? (_password = CallExpensiveOperation());
private string Password => _password ??= CallExpensiveOperation();
CallExpensiveOperation();
es während der Erstellung / Initialisierung des enthaltenen Objekts aufgerufen wird und nicht beim ersten Zugriff auf die Eigenschaft.Die Hauptverwendung in meinem Code ist die verzögerte Initialisierung, wie andere bereits erwähnt haben.
Ein weiterer Grund für private Eigenschaften über Felder ist, dass private Eigenschaften viel, viel einfacher zu debuggen sind als private Felder. Ich möchte häufig Dinge wissen wie "Dieses Feld wird unerwartet festgelegt. Wer ist der erste Anrufer, der dieses Feld festlegt?" und es ist viel einfacher, wenn Sie einfach einen Haltepunkt auf den Setter setzen und loslegen können. Sie können sich dort anmelden. Dort können Sie Leistungsmetriken eingeben. Sie können Konsistenzprüfungen durchführen, die im Debug-Build ausgeführt werden.
Grundsätzlich kommt es darauf an: Code ist weitaus leistungsfähiger als Daten . Jede Technik, mit der ich den Code schreiben kann, den ich brauche, ist gut. In Feldern können Sie keinen Code schreiben, in den Eigenschaften jedoch.
quelle
Ich persönlich benutze dies auch dann, wenn ich keine Logik für den Getter oder Setter einer Eigenschaft benötige. Die Verwendung einer Eigenschaft, auch einer privaten, hilft dabei, Ihren Code zukunftssicher zu machen, sodass Sie die Logik bei Bedarf später einem Getter hinzufügen können.
Wenn ich der Meinung bin, dass eine Eigenschaft möglicherweise zusätzliche Logik erfordert, verpacke ich sie manchmal in eine private Eigenschaft, anstatt ein Feld zu verwenden, damit ich meinen Code später nicht ändern muss.
In einem halbbezogenen Fall (obwohl anders als Ihre Frage) verwende ich sehr häufig die privaten Setter auf öffentlichen Grundstücken:
Dies gibt Ihnen einen öffentlichen Getter, hält den Setter jedoch privat.
quelle
Eine gute Verwendung für private Get Only-Eigenschaften sind berechnete Werte. Mehrmals hatte ich Eigenschaften, die schreibgeschützt sind und nur eine Berechnung über andere Felder in meinem Typ durchführen. Es ist einer Methode nicht würdig und für andere Klassen nicht interessant, also ist es Privateigentum.
quelle
Eine verzögerte Initialisierung ist ein Ort, an dem sie ordentlich sein können, z
Dann können Sie schreiben:
this.MyType
überall und nichtthis.mytype.Value
und umfassen die Tatsache, dass es träge an einem einzigen Ort instanziiert wird.Eine Schande ist, dass C # das Scoping des Hintergrundfelds für die Eigenschaft nicht unterstützt (dh es innerhalb der Eigenschaftsdefinition deklariert), um es vollständig auszublenden und sicherzustellen, dass immer nur über die Eigenschaft darauf zugegriffen werden kann.
quelle
field-declaration
s Scoped in istaccessor-declarations
seit langem die Nummer 1 auf meiner C # -Wunschliste . Wenn Sie das in einer (tatsächlichen) zukünftigen Version entwerfen und implementieren könnten, dann werde ich Ihnen einen Kuchen backen.Die einzige Verwendung, an die ich denken kann
quelle
private bool IsPasswordSet() { return !String.IsNullOrEmpty(_password); }
Eigenschaften und Felder sind nicht eins zu eins. Bei einer Eigenschaft handelt es sich um die Schnittstelle einer Klasse (unabhängig davon, ob es sich um ihre öffentliche oder interne Schnittstelle handelt), während sich ein Feld um die Implementierung der Klasse handelt. Eigenschaften sollten nicht als eine Möglichkeit gesehen werden, nur Felder verfügbar zu machen, sondern als eine Möglichkeit, die Absicht und den Zweck der Klasse verfügbar zu machen.
So wie Sie Eigenschaften verwenden, um Ihren Verbrauchern einen Vertrag über die Zusammensetzung Ihrer Klasse vorzulegen, können Sie sich aus sehr ähnlichen Gründen auch einen Vertrag vorlegen. Also ja, ich benutze private Immobilien, wenn es Sinn macht. Manchmal kann eine private Eigenschaft Implementierungsdetails wie das verzögerte Laden, die Tatsache, dass eine Eigenschaft wirklich ein Konglomerat aus mehreren Feldern und Aspekten ist, oder dass eine Eigenschaft bei jedem Aufruf virtuell instanziiert werden muss (think
DateTime.Now
). Es gibt definitiv Zeiten, in denen es sinnvoll ist, dies auch für sich selbst im Backend der Klasse durchzusetzen.quelle
Ich benutze sie in der Serialisierung, mit Dingen wie
DataContractSerializer
oder protobuf-net, die diese Verwendung unterstützen (XmlSerializer
nicht). Dies ist nützlich, wenn Sie ein Objekt im Rahmen der Serialisierung vereinfachen müssen:quelle
Eine Sache, die ich die ganze Zeit mache, ist das Speichern von "globalen" Variablen / Cache in
HttpContext.Current
quelle
Ich benutze sie ab und zu. Sie können das Debuggen vereinfachen, wenn Sie einfach einen Haltepunkt in der Eigenschaft einfügen oder eine Protokollierungsanweisung usw. hinzufügen können.
Kann auch nützlich sein, wenn Sie später den Typ Ihrer Daten auf irgendeine Weise ändern müssen oder wenn Sie Reflektion verwenden müssen.
quelle
Ich verwende private Eigenschaften, um den Code für den Zugriff auf Unter-Eigenschaften zu reduzieren, die häufig verwendet werden.
Es ist nützlich, wenn es viele Untereigenschaften gibt.
quelle
Es ist üblich, Mitglieder nur mit get / set-Methoden zu ändern, auch private. Die Logik dahinter ist, dass Sie wissen, dass sich Ihr Get / Set immer auf eine bestimmte Art und Weise verhält (z. B. Ereignisse auslösen), was nicht sinnvoll erscheint, da diese nicht in das Eigenschaftsschema aufgenommen werden ... aber alte Gewohnheiten sterben schwer.
quelle
Es ist absolut sinnvoll, wenn mit dem Eigenschaftssatz oder -abruf eine Logik verknüpft ist (denken Sie an eine verzögerte Initialisierung) und die Eigenschaft an einigen Stellen in der Klasse verwendet wird.
Wenn es nur ein gerades Hintergrundfeld ist? Als guter Grund fällt mir nichts ein.
quelle
Ich weiß, dass diese Frage sehr alt ist, aber die folgenden Informationen waren in keiner der aktuellen Antworten enthalten.
Wenn Sie Ihre Abhängigkeiten einfügen, möchten Sie möglicherweise einen Getter für eine Eigenschaft und keinen Setter, da dies eine schreibgeschützte Eigenschaft bedeuten würde. Mit anderen Worten, die Eigenschaft kann nur im Konstruktor festgelegt und von keinem anderen Code innerhalb der Klasse geändert werden.
Außerdem gibt Visual Studio Professional Informationen zu einer Eigenschaft und nicht zu einem Feld aus, sodass Sie leichter sehen können, welches Feld verwendet wird.
quelle
Nun, wie niemand erwähnt hat, können Sie damit Daten validieren oder Variablen sperren.
Validierung
Verriegeln
Hinweis: Wenn Sie eine Referenz sperren, sperren Sie den Zugriff auf Mitglieder des referenzierten Objekts nicht.
Lazy Reference: Wenn Sie faul laden, müssen Sie es möglicherweise asynchron ausführen, wofür es heutzutage AsyncLazy gibt . Wenn Sie ältere Versionen als das Visual Studio SDK 2015 verwenden oder es nicht verwenden, können Sie auch AsyncEx AsyncLazy verwenden .
quelle
Einige exotischere Verwendungen expliziter Felder umfassen:
ref
oderout
mit dem Wert verwenden - vielleicht weil es einInterlocked
Zähler iststruct
expliziten Layout (möglicherweise zur Zuordnung zu einem C ++ - Speicherauszug oderunsafe
Code).BinaryFormatter
mit automatischer Feldbehandlung verwendet (durch Ändern in Auto-Requisiten werden die Namen geändert und somit der Serializer beschädigt).quelle