Freigeben über


readonly (C#-Referenz)

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

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

    Ein readonly Feld kann nicht zugewiesen werden, nachdem der Konstruktor beendet wurde. Diese Regel hat unterschiedliche Auswirkungen auf Werttypen 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, das ein readonly Bezugstyp ist, immer auf dasselbe Objekt verweisen. Dieses Objekt ist möglicherweise nicht unveränderlich. Der readonly Modifizierer verhindert, dass der Feldwert durch eine andere Instanz des Verweistyps ersetzt wird. Der Modifizierer verhindert jedoch nicht, dass die Instanzdaten des Felds über das schreibgeschützte Feld geändert werden.

    Warnung

    Ein extern sichtbarer Typ, der ein extern sichtbares readonly Feld enthält, bei dem es sich um einen änderbaren Referenztyp handelt, kann ein Sicherheitsrisiko darstellen und eine Warnung von CA2104 auslösen: "Readonly veränderbare Referenztypen nicht deklarieren."

  • Gibt in einer readonly struct Typdefinition an, readonly dass der Strukturtyp unveränderlich ist. Weitere Informationen finden Sie im readonly Strukturabschnitt des Artikels "Strukturtypen ".

  • Gibt in einer Instanzmitgliedsdeklaration innerhalb eines Strukturtyps an, readonly dass ein Instanzmemm den Status der Struktur nicht ändert. Weitere Informationen finden Sie im Abschnitt "Instanzenmitglieder" des Artikels "Strukturtypen".

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

Readonly-Feldbeispiel

In diesem Beispiel kann der Wert des Felds year in der Methode ChangeYearnicht geändert werden, obwohl ihm im Klassenkonstruktor ein Wert zugewiesen wurde:

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

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

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

    public readonly int y = 5;
    
  • In einem Instanzkonstruktor der Klasse, der die Instanzfelddeklaration enthält.

  • Im statischen Konstruktor der Klasse, die die statische Felddeklaration enthält.

Diese Konstruktorkontexte sind auch die einzigen Kontexte, in denen es gültig ist, ein readonly Feld als Out - oder Ref-Parameter zu übergeben.

Hinweis

Das readonly Schlüsselwort unterscheidet sich vom Schlüsselwort const . Ein const Feld kann nur bei der Deklaration des Felds initialisiert werden. Ein readonly Feld kann mehrmals in der Felddeklaration und in einem beliebigen Konstruktor zugewiesen werden. readonly Daher können Felder je nach verwendetem Konstruktor unterschiedliche Werte aufweisen. Während ein const Feld eine Kompilierungszeitkonstante ist, kann das readonly Feld wie im folgenden Beispiel für Laufzeitkonstanten verwendet werden:

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 das folgende Beispiel verwenden:

p2.y = 66;        // Error

Sie erhalten die Compilerfehlermeldung:

Ein readonly-Feld kann nicht zugewiesen werden (außer in einem Konstruktor oder einem Variableninitialisierer)

Schreibgeschützte Instanzmember

Sie können auch den readonly-Modifizierer verwenden, um zu deklarieren, dass ein Instanzmember den Zustand einer Struktur nicht ändert.

public readonly double Sum()
{
    return X + Y;
}

Hinweis

Bei einer Lese-/Schreibeigenschaft können Sie den readonly Modifizierer zum get-Accessor hinzufügen. Einige get Accessoren können eine Berechnung durchführen und das Ergebnis zwischenspeichern, anstatt einfach den Wert eines privaten Felds zurückzugeben. Durch das Hinzufügen des readonly Modifizierers zum get Accessor wird sichergestellt, dass der get Accessor den internen Zustand des Objekts nicht ändert, indem ein Ergebnis zwischengespeichert wird.

Weitere Beispiele finden Sie im Abschnitt „Instanzenmitglieder“ des Artikels „Strukturtypen“.

Beispiel für Ref readonly Rückgabe

Der readonly Modifizierer für ein ref return Element gibt an, dass der zurückgegebene Verweis nicht geändert werden kann. Im folgenden Beispiel wird ein Verweis auf den Ursprung zurückgegeben. Er verwendet den readonly Modifizierer, um anzugeben, dass Aufrufer 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 kein readonly struct sein. Jeder Typ, der von ref zurückgegeben werden kann, kann auch von ref readonly zurückgegeben werden.

Readonly ref readonly return example

A ref readonly return kann auch mit readonly Instanzmembern für struct Typen verwendet werden:

public struct ReadonlyRefReadonlyExample
{
    private int _data;

    public readonly ref readonly int ReadonlyRefReadonly(ref int reference)
    {
        // _data = 1; // Compile error if uncommented.
        return ref reference;
    }
}

Die Methode gibt im Wesentlichen einen readonly-Verweis zusammen mit dem Instanzmitglied (in diesem Fall eine Methode) zurück, ohne Instanzfelder ändern zu können readonly.

C#-Sprachspezifikation

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

Sie können auch die Vorschläge zur Sprachspezifikation sehen:

Siehe auch