readonly (C#-Referenz)readonly (C# Reference)

Das Schlüsselwort readonly ist ein Modifizierer, der in drei Kontexten verwendet werden kann:The readonly keyword is a modifier that can be used in three contexts:

  • In einer Felddeklaration gibt readonly an, dass die Zuweisung zum Feld nur als Teil der Deklaration oder in einem Konstruktor derselben Klasse erfolgen kann.In a field declaration, readonly indicates that assignment to the field can only occur as part of the declaration or in a constructor in the same class. Ein readonly-Feld kann innerhalb der Felddeklaration und des Konstruktors mehrmals zugewiesen und neu zugewiesen werden.A readonly field can be assigned and reassigned multiple times within the field declaration and constructor.

    Ein readonly-Feld kann nicht zugewiesen werden, sobald der Konstruktor vorhanden ist.A readonly field cannot be assigned after the constructor exits. Dies hat verschiedene Auswirkungen auf Wert- und Verweistypen:That has different implications for value types and reference types:

    • Da Werttypen ihre Daten direkt enthalten, ist ein Feld des Werttyps readonly unveränderlich.Because value types directly contain their data, a field that is a readonly value type is immutable.
    • Da Verweistypen einen Verweis auf ihre Daten enthalten, muss ein Feld des Verweistyps readonly immer auf das gleiche Objekt verweisen.Because reference types contain a reference to their data, a field that is a readonly reference type must always refer to the same object. Dieses Objekt ist nicht unveränderlich.That object is not immutable. Der readonly-Modifizierer verhindert, dass das Feld durch eine andere Instanz des Verweistyps ersetzt wird.The readonly modifier prevents the field from being replaced by a different instance of the reference type. Der Modifizierer verhindert jedoch nicht, dass die Instanzdaten des Felds durch das schreibgeschützte Feld geändert werden.However, the modifier does not prevent the instance data of the field from being modified through the read-only field.

    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.“An externally visible type that contains an externally visible read-only field that is a mutable reference type may be a security vulnerability and may trigger warning CA2104 : "Do not declare read only mutable reference types."

  • In einer readonly struct-Definition gibt readonly an, dass struct unveränderlich ist.In a readonly struct definition, readonly indicates that the struct is immutable.

  • 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.In a ref readonly method return, the readonly modifier indicates that method returns a reference and writes are not allowed to that reference.

Die letzten beiden Kontexte wurden in C# 7.2 hinzugefügt.The final two contexts were added in C# 7.2.

Beispiel für ein readonly-FeldReadonly field example

In diesem Beispiel kann der Wert des Felds year nicht zur Methode ChangeYear geändert werden, obwohl ihm im Klassenkonstruktor ein Wert zugewiesen ist:In this example, the value of the field year cannot be changed in the method ChangeYear, even though it is assigned a value in the class constructor:

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

Sie können einem readonly-Feld nur in den folgenden Kontexten einen Wert zuweisen:You can assign a value to a readonly field only in the following contexts:

  • Wenn die Variable in der Deklaration initialisiert ist, z.B.:When the variable is initialized in the declaration, for example:

    public readonly int y = 5;
    
  • In einem Instanzenkonstruktor der Klasse, die die Deklaration des Instanzfelds enthält.In an instance constructor of the class that contains the instance field declaration.

  • Im statischen Konstruktor der Klasse, die die Deklaration des statischen Felds enthält.In the static constructor of the class that contains the static field declaration.

Diese Konstruktorkontexte sind auch die einzigen Kontexte, in denen es gültig ist, ein readonly-Feld als out- oder ref-Parameter zu übergeben.These constructor contexts are also the only contexts in which it is valid to pass a readonly field as an out or ref parameter.

Hinweis

Das Schlüsselwort readonly unterscheidet sich vom Schlüsselwort const.The readonly keyword is different from the const keyword. Ein const-Feld kann nur bei der Deklaration des Felds initialisiert werden.A const field can only be initialized at the declaration of the field. Ein readonly-Feld kann mehrere Male in der Felddeklaration und in einem Konstruktor zugewiesen werden.A readonly field can be assigned multiple times in the field declaration and in any constructor. Daher können readonly-Felder abhängig vom verwendeten Konstruktor über unterschiedliche Werte verfügen.Therefore, readonly fields can have different values depending on the constructor used. Außerdem ist ein const-Feld eine Kompilierzeitkonstante, während ein readonly-Feld wie im folgenden Beispiel für Laufzeitkonstanten verwendet werden kann:Also, while a const field is a compile-time constant, the readonly field can be used for runtime constants as in the following example:

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

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

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

    public static void Main()
    {
        SampleClass p1 = new SampleClass(11, 21, 32);   // OK
        Console.WriteLine($"p1: x={p1.x}, y={p1.y}, z={p1.z}");
        SampleClass p2 = new SampleClass();
        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:In the preceding example, if you use a statement like the following example:

p2.y = 66;        // Error

erhalten Sie die Compilerfehlermeldung:you will get the compiler error message:

A readonly field cannot be assigned to (except in a constructor or a variable initializer)

Beispiel für readonly structReadonly struct example

Der readonly-Modifizierer für eine struct-Definition deklariert, dass die Struktur unveränderlich ist.The readonly modifier on a struct definition declares that the struct is immutable. Jedes Instanzfeld für struct muss mit readonly markiert sein, wie im folgenden Beispiel gezeigt:Every instance field of the struct must be marked readonly, as shown in the following example:

public readonly struct Point
{
    public double X { get; }
    public double Y { get; }

    public Point(double x, double y) => (X, Y) = (x, y);

    public override string ToString() => $"({X}, {Y})";
}

Das vorhergehende Beispiel verwendet schreibgeschützte automatische Eigenschaften, um den Speicher zu deklarieren.The preceding example uses readonly auto properties to declare its storage. Dadurch wird der Compiler angewiesen, readonly-Unterstützungsfelder für diese Eigenschaften zu erstellen.That instructs the compiler to create readonly backing fields for those properties. Sie können readonly-Felder auch direkt deklarieren:You could also declare readonly fields directly:

public readonly struct Point
{
    public readonly double X;
    public readonly double Y;

    public Point(double x, double y) => (X, Y) = (x, y);

    public override string ToString() => $"({X}, {Y})";
}

Das Hinzufügen eines nicht als readonly markierten Felds generiert den Compilerfehler CS8340: Instanzfelder von schreibgeschützten Strukturen müssen schreibgeschützt sein.Adding a field not marked readonly generates compiler error CS8340: "Instance fields of readonly structs must be readonly."

Rückgabebeispiel für ref readonlyRef readonly return example

Der Modifizierer readonly für ref return gibt an, dass die zurückgegebene Referenz nicht geändert werden kann.The readonly modifier on a ref return indicates that the returned reference cannot be modified. Das folgende Beispiel gibt einen Verweis auf den Ursprung zurück.The following example returns a reference to the origin. Der readonly-Modifizierer gibt dabei an, dass die aufrufenden Funktionen den Ursprung nicht ändern können:It uses the readonly modifier to indicate that callers cannot modify the origin:

private static readonly Point origin = new Point(0, 0);
public static ref readonly Point Origin => ref origin;

Der zurückgegebene Typ muss nicht readonly struct aufweisen.The type returned doesn't need to be a readonly struct. Jeder Typ, der von ref zurückgegeben werden kann, kann auch von ref readonly zurückgegeben werden.Any type that can be returned by ref can be returned by ref readonly.

C#-SprachspezifikationC# language specification

Weitere Informationen erhalten Sie unter C#-Sprachspezifikation.For more information, see the C# Language Specification. Die Sprachspezifikation ist die verbindliche Quelle für die Syntax und Verwendung von C#.The language specification is the definitive source for C# syntax and usage.

Siehe auchSee also