Eigenschaften vs Methoden

135

Kurze Frage: Wann entscheiden Sie sich für die Verwendung von Eigenschaften (in C #) und wann für die Verwendung von Methoden?

Wir sind mit dieser Debatte beschäftigt und haben einige Bereiche gefunden, in denen es fraglich ist, ob wir eine Eigenschaft oder eine Methode verwenden sollten. Ein Beispiel ist folgendes:

public void SetLabel(string text)
{
    Label.Text = text;
}

Im Beispiel Label handelt es sich um ein Steuerelement auf einer ASPX-Seite. Gibt es ein Prinzip, das die Entscheidung (in diesem Fall) bestimmen kann, ob dies eine Methode oder eine Eigenschaft sein soll?

Ich werde die Antwort akzeptieren, die am allgemeinsten und umfassendsten ist, aber auch das Beispiel berührt, das ich gegeben habe.

Trumpi
quelle
2
-1 Diese Frage wurde schon einmal gestellt und beantwortet: stackoverflow.com/questions/164527/…
Element
Die Vor- und Nachteile von Methode / Feld / Eigenschaft können lange Debatten erzeugen. Einige allgemeine Verwendungszwecke für Eigenschaften: Wenn Sie private / geschützte Felder möchten, diese aber gleichzeitig verfügbar machen möchten. Eine andere Verwendung besteht darin, nicht nur Anweisungen, sondern auch Ausdrücke (Aktionen, wenn Sie möchten) und sogar if()Überprüfungen (gemäß MSDN) zu haben. Dies ist jedoch schwierig, da der Benutzer nicht immer die Verarbeitungskosten für den Zugriff auf eine Variable (Eigenschaft) kennt (dh der Code ist nicht verfügbar) und aus Gründen der Strenge die Eigenschaft einem Benchmarking unterzogen werden müsste. Oh, und ein "Bonus", Sie können keine Zeiger mit Eigenschaften verwenden.
Mireazma

Antworten:

145

Aus dem Abschnitt Auswahl zwischen Eigenschaften und Methoden der Entwurfsrichtlinien für die Entwicklung von Klassenbibliotheken:

Im Allgemeinen repräsentieren Methoden Aktionen und Eigenschaften repräsentieren Daten. Eigenschaften sollen wie Felder verwendet werden, was bedeutet, dass Eigenschaften nicht rechnerisch komplex sein oder Nebenwirkungen hervorrufen sollten. Wenn es nicht gegen die folgenden Richtlinien verstößt, sollten Sie eine Eigenschaft anstelle einer Methode verwenden, da weniger erfahrene Entwickler die Verwendung von Eigenschaften einfacher finden.

Ken Browning
quelle
3
Obwohl ich mit vielem einverstanden bin, denke ich nicht, dass der Teil über Nebenwirkungen richtig ist. Beispielsweise ist "Farbe" häufig eine Eigenschaft eines Objekts und hat offensichtliche Nebenwirkungen (Ändern der Farbe eines Objekts). Das Ändern von Eigenschaften hat den offensichtlichen Nebeneffekt, dass der Objektstatus geändert wird.
Erik Funkenbusch
46
Mystere Man Farbwechsel ist der gewünschte Effekt, kein Nebeneffekt. Nebenwirkung ist etwas, das nicht in der primären Aktion beabsichtigt ist.
Muhammad Hasan Khan
2
@Mystere Man: Definitiv das Ändern der Farbe ist kein Nebeneffekt, ich stimme dieser Antwort voll und ganz zu
Ahmed Said
2
"Weil weniger erfahrene Entwickler Eigenschaften einfacher zu verwenden finden." - Aus meiner Sicht ist dies der einzige Grund, Eigenschaften freizulegen. Aber habe ich recht
Tsabo
2
Was ist der Unterschied zwischen der internen Implementierung einer Eigenschaft und einer Methode? Wird bei Verwendung einer Eigenschaft etwas in den Aufrufstapel verschoben? Wenn nicht, wie wird es sonst gehandhabt?
Praveen
57

Ja, wenn Sie nur das Abrufen und Einstellen durchführen, verwenden Sie eine Eigenschaft.

Wenn Sie etwas Komplexes tun, das mehrere Datenelemente betreffen kann, ist eine Methode besser geeignet. Oder wenn Ihr Getter Parameter oder Ihr Setter mehr als einen Wertparameter akzeptiert.

In der Mitte befindet sich eine Grauzone, in der die Linie etwas unscharf sein kann. Es gibt keine feste Regel und verschiedene Leute sind sich manchmal nicht einig, ob etwas eine Eigenschaft oder eine Methode sein soll. Das Wichtigste ist nur, (relativ) konsistent zu sein, wie Sie es tun (oder wie Ihr Team es tut).

Sie sind weitgehend austauschbar, aber eine Eigenschaft signalisiert dem Benutzer, dass die Implementierung relativ "einfach" ist. Oh und die Syntax ist etwas sauberer.

Im Allgemeinen ist meine Philosophie, dass wenn Sie anfangen, einen Methodennamen zu schreiben, der mit get oder set beginnt und null bzw. einen Parameter annimmt, dies ein Hauptkandidat für eine Eigenschaft ist.

Cletus
quelle
1
Abgestimmt. Das ist nicht richtig. Die Komplexität eines Getters oder Setters ist im Getter / Setter-Code enthalten. Wie komplex es ist, ist überhaupt nicht relevant und auch nicht, wenn es "mehrere Datenelemente betrifft". Es ist wahr, dass nicht standardmäßige oder mehrere Parameter eine Methode erfordern, aber ansonsten ist diese Antwort nicht korrekt.
Hal50000
Der erste Satz erklärt alles. Bravo.
SWIIWII
13

Eigenschaften sind eine Möglichkeit, Daten von einem Objekt einzufügen oder abzurufen. Sie erstellen eine Abstraktion über Variablen oder Daten innerhalb einer Klasse. Sie sind analog zu Gettern und Setzern in Java.

Methoden kapseln eine Operation.

Im Allgemeinen verwende ich Eigenschaften, um einzelne Datenbits oder kleine Berechnungen für eine Klasse wie die Umsatzsteuer verfügbar zu machen. Was sich aus der Anzahl der Artikel und deren Kosten in einem Warenkorb ergibt.

Ich verwende Methoden, wenn ich eine Operation erstelle, z. B. das Abrufen von Daten aus der Datenbank. Jede Operation mit beweglichen Teilen ist ein Kandidat für eine Methode.

In Ihrem Codebeispiel würde ich es in eine Eigenschaft einschließen, wenn ich außerhalb der enthaltenden Klasse darauf zugreifen muss:

public Label Title 
{
   get{ return titleLabel;}
   set{ titleLabel = value;}
}

Text einstellen:

Title.Text = "Properties vs Methods";

Wenn ich nur die Text-Eigenschaft des Labels festlegen würde, würde ich dies folgendermaßen tun:

public string Title 
{
   get{ return titleLabel.Text;}
   set{ titleLabel.Text = value;}
}

Text einstellen:

Title = "Properties vs Methods";
Chuck Conway
quelle
12

Wenn Sie eine tatsächliche Eigenschaft Ihres Objekts festlegen, verwenden Sie eine Eigenschaft.

Wenn Sie eine Aufgabe / Funktionalität ausführen, verwenden Sie eine Methode.

In Ihrem Beispiel wird eine bestimmte Eigenschaft festgelegt.

Wenn Ihre Funktionalität jedoch AppendToLabel wäre, würden Sie eine Methode verwenden.

Robin Day
quelle
11

Beim Durchsuchen von MSDN habe ich eine Referenz zu Eigenschaften und Methoden gefunden , die einige gute Richtlinien zum Erstellen von Methoden enthält:

  • Die Operation ist eine Konvertierung, wie z Object.ToString.
  • Der Vorgang ist so teuer, dass Sie dem Benutzer mitteilen möchten, dass er das Ergebnis zwischenspeichern sollte.
  • Das Erhalten eines Eigenschaftswerts mit dem get-Accessor hätte einen beobachtbaren Nebeneffekt.
  • Wenn Sie das Mitglied zweimal hintereinander anrufen, werden unterschiedliche Ergebnisse erzielt.
  • Die Reihenfolge der Ausführung ist wichtig. Beachten Sie, dass die Eigenschaften eines Typs in beliebiger Reihenfolge festgelegt und abgerufen werden können sollten.
  • Das Mitglied ist statisch, gibt jedoch einen Wert zurück, der geändert werden kann.
  • Das Mitglied gibt ein Array zurück. Eigenschaften, die Arrays zurückgeben, können sehr irreführend sein. Normalerweise muss eine Kopie des internen Arrays zurückgegeben werden, damit der Benutzer den internen Status nicht ändern kann. Dies führt zusammen mit der Tatsache, dass ein Benutzer leicht annehmen kann, dass es sich um eine indizierte Eigenschaft handelt, zu ineffizientem Code.
Gavin Miller
quelle
Ich bin damit einverstanden, dass dies gegebenenfalls sinnvoll ist. Aber habe ich Recht, dass die Verwendung von Eigenschaften über die XAML-Bindung in WPF keine andere Wahl lässt, als die entsprechenden Aktionen im Setter auszuführen? (besonders bei einem neuen SelectedItem für ComboBoxen, ListBoxen usw.)
Nicolas
9

Sie müssen sich nur den Namen ansehen ... "Property". Was heißt das? Das Wörterbuch definiert es auf viele Arten, aber in diesem Fall passt "ein wesentliches oder unterscheidendes Attribut oder die Qualität einer Sache" am besten.

Denken Sie über den Zweck der Aktion nach. Ändern oder rufen Sie tatsächlich "ein wesentliches oder charakteristisches Attribut" ab? In Ihrem Beispiel verwenden Sie eine Funktion, um eine Eigenschaft eines Textfelds festzulegen. Das scheint irgendwie albern, nicht wahr?

Eigenschaften sind wirklich Funktionen. Sie alle werden zu getXXX () und setXXX () kompiliert. Es versteckt sie nur in syntaktischem Zucker, aber es ist Zucker, der dem Prozess eine semantische Bedeutung verleiht.

Denken Sie an Eigenschaften wie Attribute. Ein Auto hat viele Eigenschaften. Farbe, MPG, Modell usw. Nicht alle Eigenschaften sind einstellbar, einige sind berechenbar.

Inzwischen ist eine Methode eine Aktion. GetColor sollte eine Eigenschaft sein. GetFile () sollte eine Funktion sein. Eine andere Faustregel lautet: Wenn sich der Status des Objekts nicht ändert, sollte es eine Funktion sein. Beispielsweise sollte CalculatePiToNthDigit (n) eine Funktion sein, da es den Status des Math-Objekts, an das es angehängt ist, nicht ändert.

Das ist vielleicht ein bisschen verwirrend, aber es läuft wirklich darauf hinaus, zu entscheiden, was Ihre Objekte sind und was sie darstellen. Wenn Sie nicht herausfinden können, ob es sich um eine Eigenschaft oder Funktion handeln soll, spielt es möglicherweise keine Rolle, welche.

Erik Funkenbusch
quelle
9

Symantisch sind Eigenschaften Attribute Ihrer Objekte. Methoden sind Verhaltensweisen Ihres Objekts.

Label ist ein Attribut und es ist sinnvoller, es zu einer Eigenschaft zu machen.

In Bezug auf die objektorientierte Programmierung sollten Sie ein klares Verständnis dafür haben, was Teil des Verhaltens ist und was lediglich ein Attribut ist.

Auto {Farbe, Modell, Marke}

Ein Auto hat die Attribute Farbe, Modell und Marke, daher ist es nicht sinnvoll, eine Methode SetColor oder SetModel zu haben, da wir das Auto symantisch nicht bitten, eine eigene Farbe festzulegen.

Wenn Sie also den Fall der Eigenschaft / Methode dem realen Objekt zuordnen oder es aus symantischer Sicht betrachten, wird Ihre Verwirrung wirklich verschwinden.

Muhammad Hasan Khan
quelle
4

Ein großes Plus für Eigenschaften ist auch, dass der Wert der Eigenschaft während des Debuggens in Visual Studio angezeigt wird.

David Karlaš
quelle
3

Ich bevorzuge es, Eigenschaften für Add / Set-Methoden mit 1 Parameter zu verwenden. Wenn mehr Parameter vorhanden sind, verwenden Sie Methoden.

abatishchev
quelle
3

Eigenschaften sollten nur einfach festgelegt werden und einen Liner erhalten. Alles andere und es sollte wirklich auf eine Methode verschoben werden. Komplexer Code sollte immer in Methoden enthalten sein.

Neil Bostrom
quelle
3

Ich verwende nur Eigenschaften für den Variablenzugriff, dh das Abrufen und Festlegen einzelner Variablen oder das Abrufen und Festlegen von Daten in Steuerelementen. Sobald irgendeine Art von Datenmanipulation benötigt / durchgeführt wird, verwende ich Methoden.

Marcus L.
quelle
3

Aus gestalterischen Gründen stellen Eigenschaften Daten oder Attribute von Klassenobjekten dar, während Methoden Aktionen oder Verhaltensweisen von Klassenobjekten sind.

In .Net, world gibt es andere Auswirkungen der Verwendung von Eigenschaften:

  • Eigenschaften werden in der Datenbindung verwendet, get_ / set_-Methoden jedoch nicht.
  • Benutzereigenschaften der XML-Serialisierung als natürlicher Mechanismus der Serilisierung.
  • Auf Eigenschaften wird über das PropertyGrid- Steuerelement und den internen ICustomTypeDescriptor zugegriffen , der effektiv verwendet werden kann, wenn Sie eine benutzerdefinierte Bibliothek schreiben.
  • Eigenschaften werden durch Attribute gesteuert . Man kann sie mit Bedacht verwenden, um aspektorientierte Software zu entwerfen.

Missverständnisse (IMHO) über die Verwendung von Eigenschaften:

  • Wird verwendet, um kleine Berechnungen verfügbar zu machen : ControlDesigner.SelectionRules Der get-Block von läuft in 72 Zeilen !!
  • Wird zum Offenlegen interner Datenstrukturen verwendet: Auch wenn eine Eigenschaft keinem internen Datenelement zugeordnet ist, kann sie als Eigenschaft verwendet werden, wenn sie ein Attribut Ihrer Klasse ist. Viceversa, auch wenn es nicht ratsam ist, ein Attribut Ihrer Klasseneigenschaften zu verwenden, Array-ähnliche Datenelemente zurückzugeben (stattdessen werden Methoden verwendet, um eine tiefe Kopie von Elementen zurückzugeben.)

In dem Beispiel hier könnte es geschrieben worden sein, mit mehr geschäftlicher Bedeutung als:

public String Title
{
    set { Label.Text = text; }
}
NileshChauhan
quelle
2

Eigenschaften sind wirklich schön, weil sie im visuellen Designer von Visual Studio zugänglich sind, vorausgesetzt, sie haben Zugang.

Sie werden verwendet, wenn Sie lediglich Einstellungen vornehmen und abrufen, und möglicherweise eine Validierung, die nicht auf eine signifikante Menge an Code zugreift. Seien Sie vorsichtig, da das Erstellen komplexer Objekte während der Validierung nicht einfach ist.

Alle anderen Methoden sind der bevorzugte Weg.

Es geht nicht nur um Semantik. Bei Verwendung unangemessener Eigenschaften tritt im Visual Studio Visual Designer eine Verrücktheit auf.

Zum Beispiel habe ich einen Konfigurationswert innerhalb einer Eigenschaft einer Klasse erhalten. Die Konfigurationsklasse öffnet tatsächlich eine Datei und führt eine SQL-Abfrage aus, um den Wert dieser Konfiguration abzurufen. Dies verursachte Probleme in meiner Anwendung, bei denen die Konfigurationsdatei von Visual Studio selbst und nicht von meiner Anwendung geöffnet und gesperrt wurde, da der Konfigurationswert nicht nur gelesen, sondern auch geschrieben wurde (über die Setter-Methode). Um dies zu beheben, musste ich es nur in eine Methode ändern.

Jeremy Edwards
quelle
1

Hier finden Sie eine Reihe guter Richtlinien für die Verwendung von Eigenschaften im Vergleich zu Methoden von Bill Wagner

  • Verwenden Sie eine Eigenschaft, wenn all dies zutrifft: Die Getter sollten einfach sein und daher wahrscheinlich keine Ausnahmen auslösen. Beachten Sie, dass dies keinen Netzwerk- (oder Datenbank-) Zugriff impliziert. Beides könnte fehlschlagen und daher eine Ausnahme auslösen.
  • Sie sollten keine Abhängigkeiten voneinander haben. Beachten Sie, dass dies das Festlegen einer Eigenschaft und deren Auswirkung auf eine andere umfassen würde. (Das Festlegen der FirstName-Eigenschaft wirkt sich beispielsweise auf eine schreibgeschützte FullName-Eigenschaft aus, die aus den Eigenschaften Vorname + Nachname besteht. Dies impliziert eine solche Abhängigkeit.)
  • Sie sollten in beliebiger Reihenfolge einstellbar sein
  • Der Getter hat keine beobachtbaren Nebenwirkungen. Beachten Sie, dass diese Richtlinie einige Formen der verzögerten Bewertung in einer Eigenschaft nicht ausschließt.
  • Die Methode muss immer sofort zurückkehren. (Beachten Sie, dass dies eine Eigenschaft ausschließt, die einen Datenbankzugriffsaufruf, einen Webdienstaufruf oder eine andere ähnliche Operation ausführt.)
  • Verwenden Sie eine Methode, wenn das Mitglied ein Array zurückgibt.
  • Wiederholte Aufrufe des Getters (ohne dazwischenliegenden Code) sollten den gleichen Wert zurückgeben.
  • Wiederholte Anrufe an den Setter (mit demselben Wert) sollten keinen Unterschied zu einem einzelnen Anruf ergeben.

  • Das get sollte keinen Verweis auf interne Datenstrukturen zurückgeben (siehe Punkt 23). Eine Methode könnte eine tiefe Kopie zurückgeben und dieses Problem vermeiden.

* Aus meiner Antwort auf eine doppelte Frage entnommen.

Chris Ballance
quelle
Bestbewertete und akzeptierte Antworten hier stackoverflow.com/a/1294189/1551 Warum die Abwertung?
Chris Ballance
2
Mir ist klar, dass ich etwas spät zur Party komme, aber diese Abwertung ist höchstwahrscheinlich darauf zurückzuführen, dass Sie Ihre Antwort kopiert haben. Durch das Einfügen von Kopien haben Sie zugegeben, dass diese Frage im Grunde ein Duplikat der anderen war. Als solches hätten Sie es als Duplikat markieren sollen, anstatt es zu beantworten. Ich empfehle, in einem Artikel über Meta zu lesen, wie doppelte Fragen behandelt werden sollen.
Joshua
0

Das ist einfach.

1: Verwenden Sie die Eigenschaft, wenn Sie möchten, dass Ihre Daten vor dem Speichern im Feld überprüft werden. Auf diese Weise bietet die Eigenschaft eine Kapselung für Ihre Felder. Denn wenn Sie Ihre Felder öffentlich lassen, kann der Endbenutzer einen beliebigen Wert zuweisen, der gemäß Ihrer Geschäftsanforderung gültig sein kann oder nicht, z. B. sollte das Alter größer als 18 Jahre sein. Bevor der Wert das entsprechende Feld speichert, müssen wir seine Gültigkeit überprüfen. Auf diese Weise repräsentieren Eigenschaften Daten.

2: Verwenden Sie die Methode, wenn Sie eine Aktion ausführen möchten, z. B. wenn Sie einige Daten als Parameter angeben und Ihre Methode eine Verarbeitung auf der Grundlage der angegebenen Werte durchführt und den verarbeiteten Wert als Ausgabe zurückgibt. Oder Sie möchten den Wert eines Feldes durch diese Berechnung ändern. "Auf diese Weise repräsentiert die Methode die Aktion".

Der Marsmensch
quelle
-1

Ich komme aus Java und habe für eine Weile die Methode get .. set .. verwendet.

Wenn ich Code schreibe, frage ich mich nicht: "Der Zugriff auf diese Daten ist einfach oder erfordert einen schweren Prozess?" Da sich die Dinge ändern können (heute ist das Abrufen dieser Eigenschaft einfach, morgen kann ein gewisser oder schwerer Prozess erforderlich sein).

Heute habe ich morgen eine Methode SetAge (int age). Ich werde auch die Methode SetAge (Geburtsdatum) haben, die das Alter anhand des Geburtsdatums berechnet.

Ich war sehr enttäuscht, dass die Compiler-Transformationseigenschaft in get und set meine Methoden Get ... und Set .. nicht als gleich betrachtet.

Marco Staffoli
quelle