Eigenschaften (C#-Programmierhandbuch)

Eine Eigenschaft ist ein Member, das einen flexiblen Mechanismus zum Lesen, Schreiben oder Berechnen des Werts eines privaten Felds bietet. Eigenschaften können wie öffentliche Datenmember verwendet werden, es sind jedoch spezielle Methoden namens Zugriffsmethoden. Dieses Feature ermöglicht den problemlosen Datenzugriff und unterstützt weiterhin die Sicherheit und Flexibilität der Methoden.

Übersicht über Eigenschaften

  • Mithilfe von Eigenschaften kann eine Klasse eine öffentliche Methode zum Abrufen und Festlegen von Werten verfügbar machen und dabei den Implementierungs- oder Verifizierungscode ausblenden.
  • Eine get-Eigenschaftenaccessor wird verwendet, um den Wert der Eigenschaft zurückzugeben. Ein set-Eigenschaftenaccessor wird verwendet, um einen neuen Wert zuzuweisen. Eine init-Eigenschaftenzugriffsmethode wird verwendet, um nur während der Objekterstellung einen neuen Wert zuzuweisen. Diese Zugriffsmethoden können über verschiedene Zugriffsebenen verfügen. Weitere Informationen finden Sie unter Einschränken des Accessorzugriffs.
  • Das Schlüsselwort value wird verwendet, um den Wert zu definieren, der von einer der Zugriffsmethoden set oder init zugewiesen wird.
  • Eigenschaften können sein: Lesen/Schreiben (beide verfügen über einen get- und set-Accessor), schreibgeschützt (verfügen über einen get-Accessor, jedoch keinen set-Accessor), oder lesegeschützt (verfügen über einen set-Accessor, jedoch keinen get Accessor). Lesegeschützte Eigenschaften sind selten und werden am häufigsten verwendet, um den Zugriff auf vertrauliche Daten einzuschränken.
  • Einfache Eigenschaften, die keinen benutzerdefinierten Accessorcode erfordern können implementiert werden, entweder als Ausdruckstextdefinitionen oder als automatisch implementierte Eigenschaften.

Eigenschaften mit Unterstützungsfeldern

Ein grundlegendes Muster zum Implementieren einer Eigenschaft umfasst ein privates Unterstützungsfeld zum Festlegen und Abrufen des Eigenschaftswerts. Der get-Accessor gibt den Wert des privaten Felds zurück, und der set-Accessor kann die Validierung einiger Daten ausführen, bevor er dem privaten Feld einen Wert zuweist. Beide Zugriffsmethoden führen möglicherweise eine Konvertierung oder eine Berechnung der Daten aus, bevor sie gespeichert oder zurückgegeben werden.

Dieses Muster wird anhand des folgenden Beispiels veranschaulicht. In diesem Beispiel stellt die TimePeriod-Klasse ein Zeitintervall dar. Intern speichert die Klasse das Zeitintervall in Sekunden in einem privaten Feld mit dem Namen _seconds. Eine Schreib-Lese-Eigenschaft mit dem Namen Hours ermöglicht dem Kunden, das Zeitintervall in Stunden anzugeben. Die get- und set-Accessoren führen jeweils die notwendige Konvertierung zwischen Stunden und Sekunden durch. Darüber hinaus prüft der set-Accessor die Daten, und löst eine ArgumentOutOfRangeException aus, wenn die Anzahl von Stunden ungültig ist.

public class TimePeriod
{
    private double _seconds;

    public double Hours
    {
        get { return _seconds / 3600; }
        set
        {
            if (value < 0 || value > 24)
                throw new ArgumentOutOfRangeException(nameof(value),
                      "The valid range is between 0 and 24.");

            _seconds = value * 3600;
        }
    }
}

Sie können auf Eigenschaften zugreifen, um den Wert abzurufen und festzulegen, wie im folgenden Beispiel gezeigt:

TimePeriod t = new TimePeriod();
// The property assignment causes the 'set' accessor to be called.
t.Hours = 24;

// Retrieving the property causes the 'get' accessor to be called.
Console.WriteLine($"Time in hours: {t.Hours}");
// The example displays the following output:
//    Time in hours: 24

Ausdruckstextdefinitionen

Häufig bestehen Eigenschaftenaccessoren aus einzeilige Anweisungen, die gerade das Ergebnis eines Ausdrucks zuweisen oder zurückgeben. Sie können diese Eigenschaften als Ausdruckskörpermember implementieren. Ausdruckstextdefinitionen bestehen aus dem =>-Symbol, gefolgt von dem Ausdruck, der der Eigenschaft zugewiesen oder aus dieser abgerufen werden soll.

Schreibgeschützte Eigenschaften können die get-Zugriffsmethode als Ausdruckskörpermember implementieren. In diesem Fall werden weder das get-Accessorschlüsselwort noch das return-Schlüsselwort verwendet. Das folgende Beispiel implementiert die schreibgeschützte Name-Eigenschaft als ein Ausdruckskörpermember.

public class Person
{
    private string _firstName;
    private string _lastName;

    public Person(string first, string last)
    {
        _firstName = first;
        _lastName = last;
    }

    public string Name => $"{_firstName} {_lastName}";
}

Sowohl die get- als auch die set-Zugriffsmethode können als Ausdruckskörpermember implementiert werden. In diesem Fall müsse die get- und set-Schlüsselwörter vorhanden sein. Das folgende Beispiel veranschaulicht die Verwendung von Ausdruckstextdefinitionen für beide Accessoren. Das return-Schlüsselwort wird nicht mit der get-Zugriffsmethode verwendet.

public class SaleItem
{
    string _name;
    decimal _cost;

    public SaleItem(string name, decimal cost)
    {
        _name = name;
        _cost = cost;
    }

    public string Name
    {
        get => _name;
        set => _name = value;
    }

    public decimal Price
    {
        get => _cost;
        set => _cost = value;
    }
}

Automatisch implementierte Eigenschaften

In einigen Fällen weisen die Zugriffsmethoden für die Eigenschaften get und set nur einen Wert zu oder rufen einen Wert aus einem Unterstützungsfeld ab, ohne zusätzliche Logik. Mithilfe von automatisch implementierten Eigenschaften können Sie Ihren Code vereinfachen, während der C#-Compiler das Unterstützungsfeld für Sie transparent bereitstellt.

Wenn eine Eigenschaft über eine get- und eine set-Zugriffsmethode (oder eine get- und init-Zugriffsmethode) verfügt, müssen beide Methoden automatisch implementiert werden. Definieren Sie eine automatisch implementierte Eigenschaft mithilfe der get- und set-Schlüsselwörter ohne jede Implementierung. Im folgenden Beispiel wird das vorherige Beispiel wiederholt, außer das Name und Price automatisch implementierte Eigenschaften sind. Das Beispiel entfernt auch den parametrisierten Konstruktor, damit SaleItem-Objekte jetzt mit einem Aufruf des parameterlosen Konstruktors und eines Objektinitialisierers initialisiert werden.

public class SaleItem
{
    public string Name
    { get; set; }

    public decimal Price
    { get; set; }
}

Automatisch implementierte Eigenschaften können unterschiedliche Zugriffsmöglichkeiten für die get- und set-Zugriffsmethoden deklarieren. Sie deklarieren in der Regel eine öffentliche get-Zugriffsmethode und eine private set-Zugriffsmethode. Weitere Informationen finden Sie im Artikel Einschränken des Zugriffsmethodenzugriffs.

Erforderliche Eigenschaften

Ab C# 11 können Sie das required-Member hinzufügen, um zu erzwingen, dass der Clientcode jede Eigenschaft oder jedes Feld initialisiert:

public class SaleItem
{
    public required string Name
    { get; set; }

    public required decimal Price
    { get; set; }
}

Um eine SaleItem zu erstellen, müssen Sie sowohl die Eigenschaft Name als auch die Eigenschaft Price mithilfe von Objektinitialisierern festlegen, wie im folgenden Code gezeigt:

var item = new SaleItem { Name = "Shoes", Price = 19.95m };
Console.WriteLine($"{item.Name}: sells for {item.Price:C2}");

C#-Programmiersprachenspezifikation

Weitere Informationen finden Sie unter Eigenschaften in der C#-Sprachspezifikation. Die Sprachspezifikation ist die verbindliche Quelle für die Syntax und Verwendung von C#.

Siehe auch