C# Eigenschaften/Attribute sollte man immer get; set; verwenden?

5 Antworten

Vom Fragesteller als hilfreich ausgezeichnet
"Muss" ich bei der Deklaration von Eigenschaften immer { get; set; } setzen?

Nein. Welchen Zugriff die Properties auf ihre Felder gewährleisten sollen, ist fallabhängig. So könnte es auch den Fall geben, dass es nur einen Lesezugriff geben soll.

Beispiel:

public int SomeNumber { get; }

// or:
public int SomeNumber { get; private set; }

Wenn du es bei der Propertydefinition zudem nur bei get/set belässt (also einem automatischen Property), werden deren Körper automatisch generiert. Das ist nicht für jeden Fall praktisch.

Ein klassisches Beispiel findet man bei der Entwicklung mit WPF. Wenn man View-gebundene Properties bei Wertänderung auch auf der grafischen Oberfläche aktualisieren möchte, braucht es in der Regel einen Methodenaufruf, der diese Wertänderung weiterkommuniziert. Eine Propertydefinition könnte dann folgendermaßen aussehen:

private string _someText;

public string SomeText
{
  get => _someText;
  set
  {
    if (_someText != value)
    {
      _someText = value;
      OnPropertyChanged(nameof(SomeText));
    }
  }
}

Da das Property nicht automatisch generiert werden soll, muss das Backing Field explizit deklariert werden. Der Getter gibt den Feldwert lediglich zurück, der Setter ändert den Wert nur, wenn der neue Wert anders ist. Dann wird auch die OnPropertyChanged-Methode aufgerufen, die die Wertänderung an andere Programmteile kommuniziert.

Beziehungsweise ist das der "cleane way to go"?

Generell die Arbeit mit Properties zu bevorzugen, wäre zu empfehlen, denn so schaffst du eine zusätzlich konfigurierbare Abstraktionsebene.

Stell dir nur einmal vor, du würdest in einem Programm mit dem Feld

public int value;

arbeiten und es gibt mehrere Stellen im Programmcode, die auf dieses Feld zugreifen (sei es nur zum Lesen oder auch zum Ändern des Wertes). Wenn dir nun plötzlich eine neue allgemeingültige Anforderung einfällt, die zum Beispiel das Setzen des Wertes limitiert (wie: Der neue Wert muss stets größer 0 sein), stehst du vor einem Problem.

Du könntest nun alle Schreibzugriffe suchen und mit der Vorprüfung versehen:

if (newValue > 0)
{
  yourObject.value = newValue;
}

Das ist allerdings mühselig und risikobehaftet. Du könntest ja einen Fall in deinem Programm übersehen/vergessen oder bei den notwendigen Programmänderungen unbeabsichtigte Fehler machen.

Mit einem Property ist es einfacher, denn bei dem brauchst du lediglich einmal die Propertydefinition ändern.

Ich weiß, dass es einige Vorteile mit sich bringt, aber gibt es auch Szenarien wo man darauf verzichten sollte?

Da fällt mir derzeit kein Szenario ein.

Denn ich habe nämlich auch gehört, dass Eigenschaften eben nur wirklich Eigenschaften sind, wenn sie aus get set und einer privaten Variable bestehen??

Es gibt eine grundsätzliche Unterscheidung zwischen Properties und Feldern.

Ein Feld stellt eine Variable dar, die innerhalb des Klassenkörpers deklariert wird.

Beispiel:

class SomeClass
{
  private int _someField;
}

Eine gängige Konvention ist es, private Variablen im Namen mit einem vorhergehenden Unterstrich zu kennzeichnen.

Ein Property wiederum ist ein Sprachkonstrukt, mit dem der (Lese-/Schreib-)Zugriff auf so ein Feld festgelegt werden kann.

Beispiel:

class SomeClass
{
  private int _number;

  public int Number
  {
    get => _number;
    protected set => _number = value;
  }
}

In diesem Beispiel haben (außerhalb der Klasse) nur Subklassen Schreibzugriff auf _number. Da sowohl Getter als auch Setter keine individuelle/spezielle Logik implementiert haben, die vom Standardweg abweicht, lässt sich all das mit einem automatischen Property abkürzen:

class SomeClass
{
  public int Number { get; protected set; }
}

Du solltest in C# nach Möglichkeit Properties verwenden. In C# gibt es nicht nur public fields, sondern eben auch Properties mit getter und setter.

{ get; set; } macht dir eben eine Auto Property, bei der du den Rest später selber bei Bedarf implementieren kannst.

Woher ich das weiß:Berufserfahrung – Software Entwickler / Devops
Jonimaker 
Fragesteller
 25.05.2023, 20:17

Ist bspw. innerhalb einer Klasse:

public string Name;

Nicht auch schon eine Property? 😅

Klar das andere ist schöner und hat Vorteile aber rein theoretisch? Es würde ja auch so funktionieren

0
Suiram1  25.05.2023, 20:51
@Jonimaker
public string Name;

Das ist übrigens keine Property. Eine Property muss immer mindesten ein getter haben. Richtig wäre es so als Property:

public string Name { get; set; }
2

Propertys sind schon sehr nützlich, da man mit diesen auch werte überprüfen kann bevor diese gesetzt werden. Und nein eine Pproperty muss nicht immer mit { get; set; } definiert sein, da wenn du folgendes schreibst:

public string Property { get; set; }

Der Kompiler macht eh nur folgendes daraus:

private string <Property>k__BackingField;

public string Property
{
   [CompilerGenerated]
   get
   {
      return <Property>k__BackingField;
   }
   [CompilerGenerated]
   set
   {
      <Property>k__BackingField = value;
   }
}

Da sieht man auch sehr gut das man in einen getter oder settter auch code schreiben kann. Dort kannst zu Beispiel die werte die gesetzt werden sollen überprüfen oder andere dinge auslösen. Weiter zu deiner Frage: Man sollte es mit Propertys eigentlich immer so machen und je nachdem ob man noch dabei was anderes ausführen möchte es nur mit { get; set; } oder mit code blöcken machen.

Woher ich das weiß:Hobby

Die Verwendung von Zugriffsfunktionen gilt als gute Programmierpraxis.

Moderne Programmierumgebungen können sie sogar automatisiert generieren.
Wenn man erst denkt, man könnte darauf verzichten und später merkt, dass sie doch ganz nützlich wären, hat man ein Refactoring vor sich.

Gründe darauf verzichten - vielleicht aus Performance-Gründen, aber eigentlich fressen sie kein Brot. Das ist wie mit einem Filter vor der Pumpe: Lässt man ihn weg, steigt die Pumpleistung minimal an, aber das Risiko einer Fehlfunktion steigt dafür stark, falls mal unerwartet Dreck reinkommt.

Reine Datenklassen ausschließlich mit Zugriffsmethoden, ohne jede fachliche Funktionalität, gelten allerdings auch als Anti-Pattern.

Woher ich das weiß:Berufserfahrung – Langjährige Berufserfahrung als IT-Berater

Ein Property ist keine Variable. Es gibt verschiedene Möglichkeiten, die man setzen kann: get, set, init ...

Zu dem kann man get und set usw. auch mit access modifier belegen (public, private, internal, ...). Warum das so ist, folgt im weiteren:

Was ein Property von einem Feld unterscheidet ist nicht nur {}, sondern auch dass es eigentlich eine oder zwei Methode(n) ist/sind.

Wenn ich mich jetzt nicht irre, kann gerade nicht nachschauen, wird ein Property zu public string get_PropertyName() {} und void set_PropertyName(string s);

Auch erkennbar ist dies, dass diese Methoden sich nicht in VisualStudio erstellen lassen, wenn passend dazu das Property existiert. VisualStudio erkennt nämlich den sonst aufkommenden Konflikt.

Properties speichern dazu auch nicht einfach nur Werde, sondern wie man es sich schon bei Methoden vorstellen kann, kann man ihnen bestimmte Bedingungen mitgeben, wo man dann einstellen kann: Wenn Wert so, dann speichern, sonst nicht. Somit könnte man im Property Email einen Email Check einbauen, während das Feld immer jeden String annimmt.