readonly (C#-Referenz)

Das Schlüsselwort readonly ist ein Modifizierer, der in vier Kontexten verwendet werden kann:

  • In einer Felddeklaration gibt readonly an, dass die Zuweisung zum Feld nur als Teil der Deklaration oder in einem Konstruktor derselben Klasse erfolgen kann. Ein readonly-Feld kann innerhalb der Felddeklaration und des Konstruktors mehrmals zugewiesen und neu zugewiesen werden.

    Ein readonly-Feld kann nicht zugewiesen werden, sobald der Konstruktor vorhanden ist. Diese Regel hat verschiedene Auswirkungen auf Wert- und Verweistypen:

    • Da Werttypen ihre Daten direkt enthalten, ist ein Feld, das ein readonly Werttyp ist, unveränderlich.
    • Da Verweistypen einen Verweis auf ihre Daten enthalten, muss ein Feld des Verweistyps readonly immer auf das gleiche Objekt verweisen. Dieses Objekt ist nicht unveränderlich. Der readonly-Modifizierer verhindert, dass das Feld durch eine andere Instanz des Verweistyps ersetzt wird. Der Modifizierer verhindert jedoch nicht, dass die Instanzdaten des Felds durch das schreibgeschützte Feld geändert werden.

    Warnung

    Ein extern sichtbarer Typ, der ein extern sichtbares schreibgeschütztes Feld enthält, bei dem es sich um einen änderbaren Verweistyp handelt, kann ein Sicherheitsrisiko darstellen und die folgende Warnung auslösen: CA2104: „Schreibgeschützte änderbare Verweistypen nicht deklarieren.“

  • In einer readonly struct-Typdefinition weist readonly darauf hin, dass der Strukturtyp unveränderlich ist. Weitere Informationen finden Sie im Abschnitt zur readonly-Struktur des Artikels Strukturtypen.

  • In einer Instanzmemberdeklaration innerhalb eines Strukturtyps gibt readonly an, dass ein Instanzmember den Zustand einer Struktur nicht ändert. Weitere Informationen finden Sie im Abschnitt readonly-Instanzmember des Artikels Strukturtypen.

  • In einer ref readonly-Methodenrückgabe gibt der readonly-Modifizierer an, dass die Methode eine Referenz zurückgibt, und Schreibvorgänge für diese Referenz nicht zulässig sind.

Die readonly struct- und ref readonly-Kontexte wurden in C# 7.2 hinzugefügt. readonly-Strukturmember wurden in C# 8.0 hinzugefügt.

Beispiel für ein readonly-Feld

In diesem Beispiel kann der Wert des Felds year nicht zur Methode ChangeYear geändert werden, obwohl ihm im Klassenkonstruktor ein Wert zugewiesen ist:

class Age
{
    private readonly int _year;
    Age(int year)
    {
        _year = year;
    }
    void ChangeYear()
    {
        //_year = 1967; // Compile error if uncommented.
    }
}

Sie können einem readonly-Feld nur in den folgenden Kontexten einen Wert zuweisen:

  • Wenn die Variable in der Deklaration initialisiert ist, z.B.:

    public readonly int y = 5;
    
  • In einem Instanzenkonstruktor der Klasse, die die Deklaration des Instanzfelds enthält.

  • Im statischen Konstruktor der Klasse, die die Deklaration des statischen Felds enthält.

Diese Konstruktorkontexte sind auch die einzigen Kontexte, in denen es zulässig ist, ein readonly-Feld als out- oder ref-Parameter zu übergeben.

Hinweis

Das Schlüsselwort readonly unterscheidet sich vom Schlüsselwort const. Ein const-Feld kann nur bei der Deklaration des Felds initialisiert werden. Ein readonly-Feld kann mehrere Male in der Felddeklaration und in einem Konstruktor zugewiesen werden. Daher können readonly-Felder abhängig vom verwendeten Konstruktor über unterschiedliche Werte verfügen. Außerdem ist ein const-Feld eine Kompilierzeitkonstante, während ein readonly-Feld wie im folgenden Beispiel für Laufzeitkonstanten verwendet werden kann:

public static readonly uint timeStamp = (uint)DateTime.Now.Ticks;
public class SamplePoint
{
    public int x;
    // Initialize a readonly field
    public readonly int y = 25;
    public readonly int z;

    public SamplePoint()
    {
        // Initialize a readonly instance field
        z = 24;
    }

    public SamplePoint(int p1, int p2, int p3)
    {
        x = p1;
        y = p2;
        z = p3;
    }

    public static void Main()
    {
        SamplePoint p1 = new SamplePoint(11, 21, 32);   // OK
        Console.WriteLine($"p1: x={p1.x}, y={p1.y}, z={p1.z}");
        SamplePoint p2 = new SamplePoint();
        p2.x = 55;   // OK
        Console.WriteLine($"p2: x={p2.x}, y={p2.y}, z={p2.z}");
    }
    /*
     Output:
        p1: x=11, y=21, z=32
        p2: x=55, y=25, z=24
    */
}

Wenn Sie im vorherigen Beispiel eine Anweisung wie die folgende verwenden:

p2.y = 66;        // Error

erhalten Sie die Compilerfehlermeldung:

Einem schreibgeschützten Feld kann nichts zugewiesen werden (außer in einem Konstruktor oder Variableninitialisierer)

Rückgabebeispiel für ref readonly

Der readonly-Modifizierer für ref return gibt an, dass der zurückgegebene Verweis nicht geändert werden kann. Das folgende Beispiel gibt einen Verweis auf den Ursprung zurück. Dabei wird über den readonly-Modifizierer angegeben, dass die aufrufenden Funktionen den Ursprung nicht ändern können:

private static readonly SamplePoint s_origin = new SamplePoint(0, 0, 0);
public static ref readonly SamplePoint Origin => ref s_origin;

Der zurückgegebene Typ muss nicht readonly struct aufweisen. Jeder Typ, der von ref zurückgegeben werden kann, kann auch von ref readonly zurückgegeben werden.

C#-Sprachspezifikation

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

Sehen Sie sich auch die Vorschläge zur Sprachspezifikation an:

Siehe auch