2010-01-28 10 views
11

Das ist etwas, mit dem ich immer in meinem Code gerungen habe. Angenommen, wir haben folgenden Code:Wenn innerhalb einer Klasse, ist es besser, seine privaten Mitglieder oder seine öffentlichen Eigenschaften zu nennen?

public class MyClass { 
    private string _myVariable; 

    public string MyVariable { 
     get { return _myVariable; } 
     set { _myVariable = value; } 
    } 

    public void MyMethod() { 
     string usingPrivateMember = _myVariable; // method A 
     string usingPublicProperty = MyVariable; // method B 
    } 
} 

Welcher Weg ist richtiger - Methode A oder B? Ich bin immer zerrissen. Methode A scheint etwas schneller zu sein, da sie nicht auf eine Eigenschaft zugreifen muss, bevor sie die reelle Variable erhält. Allerdings ist Methode B sicherer, denn wenn der Getter für MyVariable eine Geschäftslogik hinzugefügt bekommt, sind Sie sicher, wenn Sie sie immer aufrufen, auch wenn es keine aktuelle Geschäftslogik gibt.

Was ist der allgemeine Konsens?

+0

und von http://stackoverflow.com/questions/1545297/fields-vs-properties-for-private-class-variables –

+1

Danke für das Finden dieser! Ich habe versucht zu suchen, aber ich denke, ich habe nicht mit richtigen Keywords suchen. – Amberite

+1

die SO-Suche ist * noch * sehr schlecht, hast du Google und 'site: stackoverflow.com' versucht? – Ash

Antwort

12

Verwenden Sie die Eigenschaft.

Ich denke, dass die Eigenschaft für dieses Feld vollständig verantwortlich sein sollte.

Es gibt viele Implementierungen, wo es keine Rolle spielt, aber es gibt viele, wo es eine Rolle spielt - eine Menge. Plus, das kann ein bisschen ein Schmerz sein, um zu finden, weil es immer aussieht richtig.

Sie werden falsch falsch nennen die Eigenschaft viel weniger Zeiten als das Feld aufrufen, und wo sind Ausnahmen zu dieser Regel, die Begründung zu dokumentieren.

+0

Ein Vorteil der Verwendung der Eigenschaft ist, dass Sie bei jedem Lese-/Schreibzugriff einen Haltepunkt setzen können. Dies ist besonders nützlich bei großen, unbekannten Code-Basen. Es ermöglicht Ihnen, im Debugger über große Codefragmente zu gehen, stoppt jedoch, wenn die Eigenschaft geändert wird. Sehr praktisch. –

+0

Es kann auch nützlich sein, wenn Unit-Tests mit Stubs durchgeführt werden, da Sie einen Wert für die Stub-Eigenschaft festlegen können, nicht jedoch für ein privates Member. – Jay

1

Dies würde wirklich davon abhängen, auf was Sie die Eigenschaft für zugreifen. Betrachten Sie die folgenden zwei Szenarien:

Szenario 1: Schreiben Sie eine Methode, eine gemeinsame Aktion auf den Daten in der Klasse zu bieten:

// assume a hypothetical class Position 

public class Circle 
{ 
    private int _radius; 
    private int _xpos; 
    private int _ypos; 

    public int Radius { get { return _radius; } } 
    public Position Center { get { return new Position(_xpos, _ypos); } } 

    public bool PointInCircle(Position other) 
    { 
     return distance(this.Center, other) < this.Radius; 
    } 
} 

das Verhalten von PointInCircle sollte das gleiche sein, wie wenn der Benutzer ausgeführt der Code darin. Daher ist es sinnvoll, die öffentlichen Eigenschaften zu verwenden.

Szenario 2: Sie schreiben eine Methode zum Bearbeiten der zugrunde liegenden Daten. Ein gutes Beispiel dafür ist die Serialisierung. Sie möchten die zugrunde liegenden Datenelemente serialisieren, im Gegensatz zu den Werten, die von Eigenschaftenaccessoren zurückgegeben werden.

1

hängt davon ab, ob Sie bei Zugriff auf die Eigenschaft einen "Validierungs" -Code aufrufen.

private int timeSinceLastPropertyAccess; 

public int TimeSinceLastPropertyAccess 
{ 
    get 
    { 
     // Reset timeSinceLastPropertyAccess to 0 
     int a = timeSinceLastPropertyAccess; 
     timeSinceLastPropertyAccess = 0; 
     return a; 
    } 
} 

Haben Sie timeSinceLastPropertyAccess zurückgesetzt werden möchten, wenn es, wenn in Ihrer Klasse verwendet wird oder nicht?

+0

Dies ist ziemlich schlecht Getter Design. Get-Methoden sollten den Status nicht ändern. –

+0

Zu True, aber es zeigt, dass Getter unerwünschte Effekte haben können, wenn sie verwendet werden. – PostMan

+2

Bedenken Sie, dass wir davon sprechen, in derselben Klasse zu sein, die diese Eigenschaften hat. Also, ob die Getter scheiße genug sind, um große Nebenwirkungen zu haben, ist ganz deine eigene Wahl. –

1

Um nur eine weitere Sache hinzuzufügen, wurde Ihr Beispiel nur nach Gettern gefragt. Die andere Hälfte davon ist Setter.

Manchmal möchten Sie, dass das Objekt die Setter verwendet, und manchmal möchten Sie, dass es sie umgehen und einfach das zugrunde liegende Feld zuweisen.

Nehmen wir zum Beispiel an, Sie haben eine Eigenschaft namens IsModified. Was würde Ihnen sagen, wann immer das Objekt geändert wurde. Sie könnten veranlassen, dass alle Ihre Setter dies auf true umkehren, falls einem der darunter liegenden Felder ein anderer Wert zugewiesen wird.

Jetzt, wenn Sie dieses Objekt hydratisieren (entweder von einer db oder woanders), würden Sie nicht wollen, dass IsModified gesetzt wird. Denn, ehrlich gesagt, ist es noch nicht modifiziert. In dieser Methode verwenden Sie also die zugrunde liegenden Feldnamen, aber in allen anderen Methoden verwenden Sie den Eigenschaften-Setter.

0

es hängt davon ab, möchten Sie tun, was die Eigenschaft tut? privat/öffentlich ist nicht wirklich wichtig, es ist so, als würde man eine Funktion aufrufen.

so wie es ist, haben Sie wirklich nur eine "Funktion" in Erwartung von etwas, wann immer dieser Wert zugegriffen oder geändert wird, eingerichtet.

Das Problem dabei ist, dass Sie kommen, um zu finden, dass Sie eine Sache tun wollen, wo es in einigen Orten zugegriffen wird, und eine andere, wenn es an anderen Orten zugegriffen wird, so dass Sie noch alle Anrufe ändern müssen 'dazu in einem der Orte.

Fakt ist, wenn ALLES, was auf diese Variable - sogar die private Klasse - Funktionen zugreifen, dies durch die Eigenschaft, die nur durch die Variable passiert, warum überhaupt die Eigenschaft zu stören? Warum erstellen Sie nicht einfach die Variable 'MyVariable'? Wenn Sie dann feststellen, dass Sie etwas tun wollen, wenn es geändert/zugegriffen wird, erstellen Sie einfach eine andere Variable mit dem Namen _MyVariable oder etwas, dann ändern Sie MyVariable als Eigenschaft für _MyVariable.

Sie sollten sich Eigenschaften wie die accessor() - und mutator() -Funktionen vorstellen, die Sie zum Schreiben verwendet haben. Der Trick dabei war, dass Sie bei jedem Zugriff auf eine Variable etwas Code schreiben wollten "Sie mussten ALLE Aufrufe dieser Variablen ändern, um stattdessen einen Accessor zu verwenden (indem Sie eine Funktion aufrufen und nicht nur auf eine Membervariable zugreifen). Aus diesem Grund würden Sie für alle Fälle 'Standard' Accessoren und Matadors erstellen. Wie ich oben erwähnt habe, haben Sie dieses Problem nicht mit C# und Eigenschaften (außer in einem lahmen Fall, wo Sie nicht an die Untermitglieder eines Mitglieds schreiben können, wenn es eine Eigenschaft ist ... WARUM ??)

Verwandte Themen