code it

Martins Tech Blog

Field oder Property, das ist hier die Frage

Manchmal ergeben sich im persönlichen Gespräch Grundsatzdiskussionen über Programmierstile und Herangehensweisen und so ist es auch in diesem Beispiel, welches sich erst kürzlich zugetragen hat. Die Frage ist: Auto-Property oder öffentliches Feld - welcher Variante ist der Vorrang zu geben?

Möchte man Daten aus einer Klasse nach außen freigeben, so ist die einfachste Möglichkeit, einfach ein Feld zu deklarieren und diesem den Zugriffsmodifizierer public zu verpassen:

public class Person
{
    public string LastName;
    public string FirstName;
}

Diese Möglichkeit gibt es, Sie widerspricht aber dem Konzept der Kapselung. Datenzugriffe mit Eigenschaften zu kapseln bietet zum einen die Möglichkeit einen dedizierten Zugriff auf private Informationen des Objektes zu gewährleisten und vielleicht auch noch eine Validierung der Daten vorzunehmen, die dann gespeichert werden sollen. Im Standardfall sieht das Ganze so aus:

private string _name;
public string Name
{
    get { return _name; }
    set { _name = value; }
}

Damit gibt es ein privates Feld, das über die Eigenschaft nach außen verfügbar gemacht wird und im Setter können dann Prüfungen durchgeführt werden.

Seit C# 3.0 gibt es nun die Möglichkeit, autoimplemented Properties zu verwenden:

public string Name { get; set; }

Damit ist noch immer eine Eigenschaft vorhanden, jedoch ist die Anlage des sogenannten Backing Fields damit nicht mehr notwendig - das übernimmt der Compiler. Was damit auch entfällt, ist die Möglichkeit zusätzliche Prüfungen im Setter hinzuzufügen.

Dieser Logik folgend, stellt sich nun aber die Frage: Warum sollte ich autoimplemented Properties verwenden und nicht public Fields (wie im ersten Beispiel). Die eben genannten offensichtlichen Vorteile der Eigenschaften entfallen bei autoimplemented Properties ja.

Grund 1: Asymmetrische Sichtbarkeit 

Eigenschaften erlauben die Definition asymmetrischer Sichtbarkeit von Getter und Setter:

public string Name { get; private set; }
public string DateOfBirth { private get; set; }

Ein Feld ist immer komplett public oder komplett private, nicht aber private beschreibbar und öffentlich schreibgeschützt.

Grund 2: Definition in Interfaces

Eigenschaften können in Interfaces festgeschrieben werden, während das für Felder nicht möglich ist.

public interface IPerson
{
    string LastName { get; set; }
    string FirstName { get; set; }
}

public class Student : IPerson
{
    public string LastName { get; set; }
    public string FirstName { get; set; }
}

Bei der Verwendung von Feldern kann man nicht sicherstellen, dass alle Objekte vom Typ Student über öffentlich verfügbare Felder für Nachname und Vorname verfügen.

Grund 3: Überschreibbarkeit

Felder können nicht überschrieben werden. Während man bei Eigenschaften problemlos in Basisklassen eine Deklaration mit virtual oder abstract vornehmen kann, um sicherzustellen, dass ein bestimmter Wert immer vorhanden ist, und die Initialisierung dann ggf. aber doch an eine spezialisiertere Klasse zu delegieren, so ist das mit Feldern nicht möglich.

Grund 4: Abwärtskompatibilität

"Dieser Code wird sich nie ändern" gibt es nicht und auch an der noch so undenkbaren Stelle wird irgendwann einmal der Zeitpunkt gekommen sein, an dem irgendeine Änderung notwendig ist. Und dann ist es gut gewappnet zu sein und eben nicht auf das Feld angewiesen zu sein, sondern die Auto-Property vielleicht aufzubrechen und hier noch zusätzliche Dinge zu machen. Der große Vorteil dann: Die Schnittstelle nach außen muss sich vielleicht nicht zwingend ändern und bereits bestehender Code der die Komponente verwendet, kann in gleicher Art und Weise weiter laufen ohne breaking changes.

Grund 5: Data Binding

Möchte man früher oder später die Objekte zur Datenbindung in WPF verwenden, so benötigt man Properties. Klar ist in diesem Fall keine Änderungsbenachrichtigung möglich - es sei denn man verwendet Aspekte, aber verwendbar sind sie so schon.

Wahrscheinlich gibt es noch den ein oder anderen weiteren Grund. Ich denke, die obige Liste bietet noch Platz für Erweiterungen.

Kommentare (1) -

  • Manu

    11.12.2012 09:03:56 | Antwort


    Manchmal ergeben sich im persönlichen Gespräch Grundsatzdiskussionen über Programmierstile und Herangehensweisen und so ist es auch in diesem Beispie....


    Solche Diskussionen sollten eigentlich schnell zu beenden sein - die .NET Field Usage Guidelines regeln das Verhalten bereits eindeutig.

    msdn.microsoft.com/.../ta31s3bc%28v=vs.71%29.aspx

Kommentar schreiben

Loading