Frage

Ich sehe eine Menge von Beispiel-Code für C # -Klassen, das dies tut:

public class Point {
    public int x { get; set; }
    public int y { get; set; }
}

Oder bei älterem Code, das gleiche mit einem expliziten privaten Träger Wert und ohne die neuen Auto-implementierten Eigenschaften:

public class Point {
    private int _x;
    private int _y;

    public int x {
        get { return _x; }
        set { _x = value; }
    }

    public int y {
        get { return _y; }
        set { _y = value; }
    }
}

Meine Frage ist, warum. Gibt es einen funktionellen Unterschied zwischen der oben tun und nur diesen Elementen öffentliche Bereiche zu machen, wie unten?

public class Point {
    public int x;
    public int y;
}

Um klar zu sein, verstehe ich den Wert von Getter und Setter, wenn Sie einige Übersetzung der zugrunde liegenden Daten müssen tun. Aber in Fällen, in denen Sie nur die Werte der Durchreise, so scheint es unnötig ausführlich.

War es hilfreich?

Lösung

ich eher zustimmen (dass es unnötig ausführlichen scheint), obwohl dies ein Problem unseres Team hat noch nicht gelöst und so unsere Coding-Standards bestehen nach wie vor auf dem ausführlichen Eigenschaften für alle Klassen.

Jeff Atwood vor mit diesem ein paar Jahren behandelt. Der wichtigste Punkt ist er im Nachhinein festgestellt, dass auf eine Eigenschaft von einem Feld zu ändern ist ein brechen Änderung in Ihrem Code; alles, was es verbraucht müssen neu kompiliert werden mit der neuen Klasse Schnittstelle zu arbeiten, so dass, wenn etwas außerhalb Ihrer Kontrolle ist Ihre Klasse raubend Sie könnten Probleme haben.

Andere Tipps

Es ist auch viel einfacher, um es später zu diesem zu ändern:

public int x { get; private set; }

Sie kapselt Einstellung und den Zugriff der Mitglieder. Wenn einige Zeit ab jetzt ein Entwickler für den Code benötigt Logik zu ändern, wenn ein Mitglied zugegriffen wird oder einstellen kann es ohne Änderung des Vertrags der Klasse erfolgen.

Die Idee ist, dass selbst wenn die zugrunde liegende Datenstruktur geändert werden muss, wird die öffentliche Schnittstelle der Klasse muß geändert werden.

C # kann manchmal Eigenschaften und Variablen unterschiedlich behandeln. Zum Beispiel können Sie nicht Eigenschaften wie ref übergeben oder out-Parameter . Also, wenn Sie die Datenstruktur aus irgendeinem Grund ändern müssen und Sie öffentliche Variablen wurden mit und jetzt müssen Sie Eigenschaften verwenden, wird Ihre Schnittstelle ändern und jetzt Code, der Eigenschaft x greift nicht mehr kompilieren wie damals, als es war variabel x:

Point pt = new Point();
if(Int32.TryParse(userInput, out pt.x))
{
     Console.WriteLine("x = {0}", pt.x);
     Console.WriteLine("x must be a public variable! Otherwise, this won't compile.");
}

Eigenschaften Unter Verwendung von Anfang an diese vermeidet, und man kann so viel frei zwicken die zugrunde liegende Implementierung fühlen, wie Sie benötigen, ohne Client-Code zu brechen.

Setter und Getter können Sie zusätzliche Abstraktionsschicht hinzuzufügen und in reiner OOP sollten Sie immer auf die Objekte zugreifen über die Schnittstelle sie an die Außenwelt bieten ...

Betrachten Sie diesen Code, mit dem Sie in asp.net sparen und welche es wäre ohne die Abstraktionsebene durch die Getter und Setter bereitgestellt nicht möglich sein:

class SomeControl
{

private string _SomeProperty  ;
public string SomeProperty 
{
  if ( _SomeProperty == null ) 
   return (string)Session [ "SomeProperty" ] ;
 else 
   return _SomeProperty ; 
}
}

Da Auto implementiert Getter die gleichen Namen für die Eigenschaft nimmt und das tatsächliche private Lagerhaltung Variablen. Wie kann man es sich in Zukunft ändern? Ich denke, der Punkt wird gesagt, dass ist es, das Auto statt Feld implementiert verwenden, so dass Sie es in der Zukunft ändern können, wenn, falls Sie Logik müssen in den Getter und Setter.

Zum Beispiel:

public string x { get; set; }

und zum Beispiel verwenden Sie bereits die x eine Menge Zeit und Sie nicht wollen, um Ihren Code zu brechen.

Wie Sie die automatische Getter Setter ändern ... zum Beispiel für Setter Sie nur eine gültige Telefonnummer Format erlauben Einstellung ... wie Sie den Code ändern, so dass nur die Klasse zu ändern ist?

Meine Idee ist es, eine neue privaten Variable hinzufügen und die gleichen x-Getter und Setter hinzuzufügen.

private string _x;

public string x { 
    get {return x}; 
    set {
        if (Datetime.TryParse(value)) {
            _x = value;
        }
    }; 
}

Ist das, was Sie meinen, indem sie es flexibel zu machen?

Auch in Betracht gezogen werden ist die Auswirkung der Änderung der öffentlichen Mitglieder, wenn es um die Bindung und Serialisierung kommt. Beide verlassen sich oft auf öffentliche Eigenschaften zum Abrufen und Sollwerte.

Sie können aber auch Stützpunkte auf Getter und Setter setzen, aber Sie können nicht auf den Feldern.

AFAIK die erzeugte CIL-Schnittstelle ist anders. Wenn Sie ein öffentliches Mitglied einer Eigenschaft ändern Sie ändern es öffentliche Schnittstelle ist und müssen jede Datei neu erstellen, die diese Klasse verwendet. Dies ist nicht erforderlich, wenn Sie nur die Umsetzung der Getter und Setter ändern.

Vielleicht nur machen Felder Öffentlichkeit konnte man führt zu einer Anemic Domain Model .

Mit freundlichen Grüßen

Es ist auch erwähnenswert, dass Sie nicht Auto Eigenschaften Read-only machen und Sie können sie inline nicht initialisieren. Beides sind Dinge, Ich mag würde in einer zukünftigen Version von .NET, um zu sehen, aber ich glaube, Sie tun können, weder in .NET 4.0.

Das einzige Mal verwende ich eine dahinter liegende Feld mit Eigenschaften in diesen Tagen, wenn meine Klasse implementiert INotifyPropertyChanged und ich brauche das OnPropertyChanged Ereignis ausgelöst, wenn eine Eigenschaft geändert wird.

Auch in diesen Situationen stelle ich die Unterstützung Felder direkt, wenn die Werte in von einem Konstruktor übergeben werden (keine Notwendigkeit, zu versuchen und feuern die OnPropertyChangedEvent (die zu diesem Zeitpunkt sowieso) NULL sein würde, irgendwo anders verwende ich die Immobilie selbst.

Sie nie wissen, wenn Sie nicht später eine Übersetzung der Daten benötigen. Sie sind darauf vorbereitet, wenn Sie Ihre Mitglieder sich verstecken. Benutzer Ihrer Klasse wird nicht kündigen, wenn Sie die Übersetzung hinzufügen, da die Schnittstelle gleich bleibt.

Der größte difrence ist, dass, wenn überhaupt Sie Ihre innere Struktur ändern, können Sie immer noch die Getter und Setter wie es ist erhalten, ihre innere Logik zu ändern, ohne dass die Benutzer Ihrer API zu verletzen.

Wenn Sie ändern, wie Sie x und y in diesem Fall erhalten, können Sie fügen Sie einfach die Eigenschaften später. Dies ist, was ich am meisten verwirrend finden. Wenn Sie die öffentlichen Membervariablen verwenden, können Sie leicht, dass später auf eine Eigenschaft ändern, und private Variablen namens _x und _y wenn Sie den Wert intern speichern müssen.

Setters und Getter schlecht sind grundsätzlich (sie sind ein schlechter OO Geruch - ich wird von kurzer aufhören zu sagen, sie sind ein Anti-Muster, weil sie wirklich notwendig sind manchmal).

Nein, es ist technisch kein Unterschied, und wenn ich in diesen Tagen wirklich Zugriff auf ein Objekt freigeben möge, ich kann es gelegentlich öffentlich statt endgültig macht einen Getter hinzuzufügen.

Die Art und Weise Getter und Setter „verkauft“ wurden, ist, dass Sie vielleicht wissen müssen, dass jemand einen Wert oder die Änderung eines wird immer -., Die nur Sinn mit Primitiven machen

Objekt Tasche Objekte wie DAOs, DTOs und Anzeigeobjekte sind von dieser Regelung ausgeschlossen, weil diese Objekte nicht in einem echten „OO Design“ Bedeutung des Wortes Gegenstand. (Sie denken nicht an „Passing Messages“ zu einem DAO, es ist einfach ein Haufen von Attribut / Wert-Paare).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top