readonly (odwołanie w C#)

Słowo readonly kluczowe to modyfikator, który może być używany w pięciu kontekstach:

  • W deklaracji pola wskazuje, readonly że przypisanie do pola może wystąpić tylko w ramach deklaracji lub konstruktora w tej samej klasie. Pole readonly można przypisać i ponownie przypisać wiele razy w deklaracji pola i konstruktorze.

    readonly Nie można przypisać pola po zakończeniu działania konstruktora. Ta reguła ma różne konsekwencje dla typów wartości i typów referencyjnych:

    • Ponieważ typy wartości bezpośrednio zawierają swoje dane, pole, które jest typem readonly wartości, jest niezmienne.
    • Ponieważ typy odwołań zawierają odwołanie do ich danych, pole, które jest typem readonly odwołania, musi zawsze odwoływać się do tego samego obiektu. Ten obiekt może nie być niezmienny. Modyfikator readonly uniemożliwia zastąpienie wartości pola innym wystąpieniem typu odwołania. Modyfikator nie uniemożliwia jednak modyfikacji danych wystąpienia pola za pomocą pola tylko do odczytu.

    Ostrzeżenie

    Zewnętrznie widoczny typ zawierający zewnętrznie widoczne pole tylko do odczytu, które jest modyfikowalnym typem odwołania, może być luką w zabezpieczeniach i może wyzwolić ostrzeżenie CA2104 : "Nie deklaruj tylko modyfikowalne typy odwołań".

  • readonly struct W definicji typu wskazuje, readonly że typ struktury jest niezmienny. Aby uzyskać więcej informacji, zobacz sekcję readonlystruktury artykułu Typy struktury.

  • W deklaracji składowej wystąpienia w typie struktury wskazuje, readonly że element członkowski wystąpienia nie modyfikuje stanu struktury. Aby uzyskać więcej informacji, zobacz sekcję readonly składowych wystąpień artykułu Typy struktury.

  • W zwracaniu ref readonlymetody modyfikator wskazuje, readonly że metoda zwraca odwołanie i zapisy nie mogą tego odwołania.

Przykład pola tylko do odczytu

W tym przykładzie wartość pola year nie może zostać zmieniona w metodzie ChangeYear, mimo że została przypisana wartość w konstruktorze klasy:

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

Wartość można przypisać do readonly pola tylko w następujących kontekstach:

  • Gdy zmienna jest inicjowana w deklaracji, na przykład:

    public readonly int y = 5;
    
  • W konstruktorze wystąpienia klasy zawierającej deklarację pola wystąpienia.

  • W konstruktorze statycznym klasy zawierającej deklarację pola statycznego.

Te konteksty konstruktora są również jedynymi kontekstami, w których prawidłowe jest przekazanie readonly pola jako parametru out lub ref .

Uwaga

Słowo readonly kluczowe różni się od słowa kluczowego const . const Pole można zainicjować tylko w deklaracji pola. Pole readonly można przypisać wiele razy w deklaracji pola i w dowolnym konstruktorze. readonly W związku z tym pola mogą mieć różne wartości w zależności od używanego konstruktora. Ponadto, gdy pole jest stałą const czasu kompilacji, readonly pole może być używane dla stałych czasu wykonywania, jak w poniższym przykładzie:

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
    */
}

W poprzednim przykładzie, jeśli używasz instrukcji podobnej do poniższego przykładu:

p2.y = 66;        // Error

zostanie wyświetlony komunikat o błędzie kompilatora:

Nie można przypisać pola tylko do odczytu (z wyjątkiem konstruktora lub inicjatora zmiennej)

Elementy członkowskie wystąpień tylko do odczytu

Można również użyć readonly modyfikatora, aby zadeklarować, że element członkowski wystąpienia nie modyfikuje stanu struktury.

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

Uwaga

W przypadku właściwości odczytu/zapisu można dodać readonly modyfikator do get metody dostępu. Niektóre get metody dostępu mogą wykonywać obliczenia i buforować wynik, a nie po prostu zwracać wartość pola prywatnego. readonly Dodanie modyfikatora do get metody dostępu gwarantuje, że get akcesorium nie modyfikuje wewnętrznego stanu obiektu przez buforowanie żadnego wyniku.

Więcej przykładów można znaleźć w readonly sekcji składowych wystąpień artykułu Typy struktury.

Ref readonly return example (Ref readonly return example)

Modyfikator readonly elementu ref return wskazuje, że zwrócone odwołanie nie może zostać zmodyfikowane. Poniższy przykład zwraca odwołanie do źródła. Używa readonly modyfikatora, aby wskazać, że osoby wywołujące nie mogą modyfikować źródła:

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

Zwracany typ nie musi być typem readonly struct. Dowolny typ, który może zostać zwrócony przez ref program , może zostać zwrócony przez ref readonly.

Przykład powrotu readonly ref readonly

Element ref readonly return może być również używany z elementami readonly członkowskimi wystąpień w struct typach:

public struct ReadonlyRefReadonlyExample
{
    private int _data;

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

Metoda zasadniczo zwraca readonly odwołanie razem z elementem członkowskim wystąpienia (w tym przypadku metodą) readonly (nie można zmodyfikować żadnych pól wystąpienia).

specyfikacja języka C#

Aby uzyskać więcej informacji, zobacz Specyfikacja języka C#. Specyfikacja języka jest ostatecznym źródłem informacji o składni i użyciu języka C#.

Można również zobaczyć propozycje specyfikacji języka:

Zobacz też