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 verwendet werden, als ob sie öffentliche Datenmitglieder sind, aber sie sind spezielle Methoden, die als Accessoren bezeichnet werden. Dieses Feature ermöglicht den einfachen Zugriff auf Daten und trägt weiterhin zur Förderung der Sicherheit und Flexibilität von Methoden bei.

Ü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. In C# 9 und höher wird eine init-Eigenschaftenzugriffsmethode 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 value-Schlüsselwort wird verwendet, um den Wert zu definieren, der von der set- oder init-Zugriffsmethode 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 Accessoren können auch eine Konvertierung oder Berechnung der Daten durchführen, bevor sie gespeichert oder zurückgegeben wird.

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 den get Accessor als Ausdruckskörperelement 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 der get Accessor als auch der set Accessor können als Ausdruckskörpermitglieder 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 dem get Accessor 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 Eigenschaften get und set Accessoren nur einen Wert zu oder rufen einen Wert aus einem Sicherungsfeld ab, ohne zusätzliche Logik einzuschlussen. 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 Accessoren deklarieren. Sie deklarieren häufig einen öffentlichen get Accessor und einen privaten set Accessor. Weitere Informationen finden Sie im Artikel zum Einschränken der Barrierefreiheit von Accessorn.

Erforderliche Eigenschaften

Ab C# 11 können Sie das required Element hinzufügen, um den Clientcode zu erzwingen, um eine beliebige Eigenschaft oder ein Beliebiges Feld zu initialisieren:

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

    public required decimal Price
    { get; set; }
}

Zum Erstellen eines SaleItemObjekts müssen Sie sowohl die Eigenschaften Price als auch die Name Eigenschaften 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