private string mWhatever;
private string Whatever
{
get
{
return this.mWhatever;
}
set
{
this.mWhatever = value;
}
}
Ich habe einige Leute gesehen, die Immobilien für jedes einzelne Mitglied machen, privat oder nicht ... macht das irgendeinen Sinn? Ich konnte es in 1% der Fälle als sinnvoll erachten, wenn Sie den Zugriff auf das Mitglied in der Klasse, in der es enthalten ist, steuern möchten, da es zu Inkonsistenzen führen und prüfen würde, ob das Element verwendet wird Mitglied hat einen Zugriff oder nicht (da Sie im Bereich der Klasse Zugriff auf beide haben).
Einige gute Antworten hier bereits, aber ich denke, die meisten von ihnen vermissen einen Punkt Ihrer Frage:
Ich denke, dass dies im Vorfeld selten für jedes einzelne Mitglied notwendig ist . Beginnen mit
Wenn Sie später zu einem Punkt kommen, an dem Sie eine Kapselung oder einen bedingten Haltepunkt für dieses bestimmte Element benötigen , können Sie es dennoch durch eine Eigenschaft mit demselben Namen ersetzen - in den meisten Fällen, ohne den verwendeten Code zu ändern
Whatever
. Aber Vorsicht, es gibt subtile Unterschiede, siehe die Antwort von Brian Rasmussen in diesem SO-Beitrag (Link auch von Emmad Kareem, +1).quelle
Einer der größten Vorteile dieses Ansatzes besteht darin, dass Sie die Kontrolle darüber haben, wann sich Ihre Variablen ändern .
Folgendes berücksichtigen.
Sie debuggen ein großes Projekt. Eine bestimmte Methode löst eine Ausnahme aus. Sie legen einen Haltepunkt fest und stellen fest, dass eine bestimmte Elementvariable einen falschen Wert hat. Angenommen, Ihr Code stützt sich sehr stark auf diese Variable, und Sie finden Hunderte von Schreibverwendungen ( Spaghetti-Szenario ). Sie können also nicht herausfinden, welche dieser Verwendungen einen schlechten Wert haben.
Wenn der Code mehrere Threads enthält, kann das Debuggen zu einem echten Albtraum werden.
Mit property können Sie einen Haltepunkt in einem Setter setzen . In Kombination mit einer Bedingung kann es in einem Durchgang festgenagelt werden.
VC ++ verfügt über Datenhaltepunkte , ist jedoch nur für nicht verwalteten Code verfügbar.
quelle
Wenn Sie keine Eigenschaft verwenden, können Sie auch ein Feld zum Speichern variabler Daten verwenden. Eigenschaften und Felder weisen erhebliche Unterschiede auf. Die meisten dieser Unterschiede sind Felder im Vergleich zu Eigenschaften . Ich schlage vor, Sie untersuchen die Unterschiede und treffen dann Ihre Wahl entsprechend Ihren Anwendungsanforderungen. Bedenken Sie jedoch, dass die Verwendung von Feldern anstelle von Eigenschaften aufgrund ihrer Art und ihres Mangels nicht die übliche OO-Praxis ist.
quelle
Private Eigenschaften können sehr nützlich sein, um das Verhalten von Dingen zu kapseln, die innerhalb Ihrer Klasse liegen. Nur weil sie privat sind, heißt das nicht, dass Sie den syntaktischen Zucker, den Ihnen die Eigenschaften verleihen, nicht ausnutzen sollten.
Das angegebene Beispiel ist jedoch schlecht. Boilerplate Property Getter und Setter wie dieses sind fast immer eine schlechte Idee. Wenn Sie C # 3.0 oder höher verwenden, sind automatische Eigenschaften eine viel bessere Idee:
Dies ist kürzer, sauberer und viel besser lesbar. Tatsächlich ist es kaum länger, als nur die Hintergrundvariable zu deklarieren.
Am wichtigsten ist jedoch, dass automatische Eigenschaften jederzeit in vollständige Eigenschaften konvertiert werden können, ohne die Semantik des restlichen Programms zu ändern! Wenn Sie also eine Validierung oder Fehlerbehandlung hinzufügen müssen, können Sie dies auf einfache Weise tun.
So wie es ist, dachte ich immer, dass es eine Schande ist, dass Sie keine schreibgeschützte Eigenschaft haben können, um zu erzwingen, dass nur in den Wert im Konstruktor geschrieben werden kann (ich bevorzuge unveränderliche Typen ), aber dies wurde in C # 6.0 als hinzugefügt "Auto-Property Initializers", mit denen Sie Folgendes tun können:
oder
zusammen mit
im Konstruktor.
quelle
Dies ist für private Eigenschaften nicht unbedingt erforderlich, ermöglicht jedoch das Ändern des Abrufs / Festlegens des zugrunde liegenden Werts für die Eigenschaft, ohne den Zugriff darauf zu ändern.
Ändern Sie beispielsweise, wie der zugrunde liegende Wert festgelegt wird:
quelle
Ja
Ich persönlich verwende dies als Caching-Mechanismus, und wir könnten es als Caching auf Eigenschaftsebene bezeichnen .
Jetzt verwende ich an anderen Stellen in meiner Klasse
Users
Eigenschaft anstelle vonusers
Feld.Eine andere mögliche Situation könnte sein, wenn Sie eine Logik in einem Feld implementieren möchten, jedoch zentral in einer Klasse. Auf diese Weise können Sie sowohl eine
GetFoo()
Methode als auch eineFoo
Eigenschaft für einfoo
Feld erstellen .quelle
Noch etwas zu beachten:
Tatsächliche Eigenschaften sind ein Implementierungsdetail. Eines der Ziele von OOP ist es, die Offenlegung von Implementierungsdetails so gering wie möglich zu halten.
Der Grund dafür ist, dass Sie weitaus mehr Kontrolle haben, wenn Sie die Eigenschaften ausblenden und sie nur durch Getter und Setter verfügbar machen. Beispielsweise kann Ihr Getter seine Eingabe validieren und verhindern, dass die Eigenschaft in einen ungültigen Zustand versetzt wird. Wenn die Möglichkeit, den Wert zu ändern, zeitkritisch ist, kann der Einsteller auch davor schützen. Der Getter kann, sollte es aus irgendeinem Grund teuer sein, den tatsächlichen Wert zu ermitteln, eine verzögerte Initialisierung und / oder Zwischenspeicherung durchführen.
Wenn Getter und Setter aufgedeckt und die Eigenschaften ausgeblendet werden, brauchen Sie manchmal überhaupt keine Eigenschaft. Ihr Getter kann den Wert beim Aufruf berechnen oder die Aufgabe an eine andere Stelle delegieren oder alles, was dazu beiträgt, dass sie der Spezifikation entspricht. An Ihrer Klasse ist es wichtig, auf welche Informationen Sie zugreifen können, und nicht, wie diese Informationen intern dargestellt werden.
Wenn nichts außerhalb der Klasse negative Konsequenzen hat, wenn es direkt auf eine Eigenschaft zugreifen kann, sollten Sie sie einfach öffentlich machen. Nach meiner Erfahrung sind solche Fälle jedoch relativ selten.
quelle
Ich weiß, dass dies eine alte Frage ist und dass alles , was @ Yusubov sagte, richtig ist, aber in Bezug auf seinen zweiten Aufzählungspunkt über bestimmte Logik im Setter, und da ich niemanden sah, der dies ausdrücklich erwähnte, wäre dies ein perfektes Beispiel für Ihre Klasse implementiert die
INotifyPropertyChanged
Schnittstelle.Dies wird in WCF und Silverlight mit einer Tonne verwendet , um zu ermitteln , wann sich eine bestimmte Eigenschaft über die Logik in ihrem Setter geändert hat, wie in der folgenden Klasse:
quelle