Udostępnij za pośrednictwem


readonly (odwołanie do funkcji readonly w C#)

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

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

    Pole readonly nie może być przypisane 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 inną instancją tego typu referencyjnego. Modyfikator nie uniemożliwia jednak zmiany danych instancji pola poprzez pole oznaczone jako 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ń".

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

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

  • W ref readonly zwracaniu z metody modyfikator readonly wskazuje, że metoda zwraca odwołanie, do którego nie można dokonywać zapisów.

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 / Notatka

Słowo readonly kluczowe różni się od słowa kluczowego const . Pole const można zainicjować tylko w deklaracji pola. Pole readonly można przypisać wiele razy w deklaracji pola i w dowolnym konstruktorze. W związku z tym readonly pola mogą mieć różne wartości w zależności od używanego konstruktora. Ponadto, gdy pole const jest stałą czasu kompilacji, pole readonly 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, użyj oświadczenia podobnego 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)

Człony instancji 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 / Notatka

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

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

Przykład zwrotu tylko do odczytu przy użyciu ref

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, może zostać zwrócony przez ref readonly.

Przykład "readonly ref" i "readonly return"

Element ref readonly return może być również używany z członkowskimi elementami readonly w typach struct.

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 także