Błędy i ostrzeżenia skojarzone z parametrami odwołania, zmiennymi i zwracanymi wartościami

Podczas pracy ze zmiennymi referencyjnymi można wygenerować następujące błędy:

  • CS0192: Pola readonly nie można użyć jako wartości ref lub out (z wyjątkiem konstruktora)
  • CS0199: Nie można użyć pola jako wartości ref lub outstatic readonly(z wyjątkiem konstruktora statycznego)
  • CS0206: Właściwość lub indeksator, które nie zwracają odwołania, nie mogą być używane jako wartość out lub ref
  • CS0631: ref i out nie są prawidłowe w tym kontekście
  • CS0767: Nie można dziedziczyć po interfejsie z określonymi parametrami typu, ponieważ powoduje to, że metoda ma przeciążenia różniące się tylko elementami ref i out
  • CS1510: Wartość ref lub out musi być zmienną z możliwością przypisania
  • CS1605: Nie można użyć zmiennej jako wartości ref lub out, ponieważ jest ona tylko do odczytu
  • CS1623: Iteratory nie mogą mieć parametrów ref, in ani out
  • CS1649: Elementy pola readonly nie mogą być używane jako wartość ref lub out (z wyjątkiem konstruktora)
  • CS1651: Składowe statycznego pola tylko do odczytu nie mogą być używane jako wartość ref lub out (z wyjątkiem konstruktora statycznego)
  • CS1655: Nie można używać pól typu jako wartości ref lub out
  • CS1657: Nie można użyć zmiennej jako wartości ref lub out
  • CS1741: Parametr lub refout nie może mieć wartości domyślnej
  • CS1939: Nie można przekazać zmiennej zakresu jako parametru out lub ref
  • CS1988: Metody asynchroniczne nie mogą mieć parametrów typu ref, in ani out
  • CS7084: Zdarzenie środowiska uruchomieniowego systemu Windows nie może zostać przekazane jako parametr out lub ref.
  • CS8196: Odwołanie do niejawnie wpisanej zmiennej out nie jest dozwolone na tej samej liście argumentów.
  • CS8325: "await" nie może być używany w wyrażeniu zawierającym operator warunkowy ref
  • CS8326: Oba wartości operatorów warunkowych muszą być wartościami ref lub żadna z nich nie może być wartością ref
  • CS8327: Wyrażenie musi być poprawne, aby było zgodne z alternatywną wartością ref
  • CS8329: Nie można użyć zmiennej jako wartości ref lub out, ponieważ jest to zmienna tylko do odczytu
  • CS8330: Nie można używać składowych zmiennej jako wartości ref lub out, ponieważ jest to zmienna tylko do odczytu
  • CS8331: Nie można przypisać wartości do zmiennej ani użyć jej po prawej stronie operatora ref przypisania, ponieważ jest to zmienna tylko do odczytu
  • CS8332: Nie można przypisać wartości do składowej zmiennej ani użyć jej po prawej stronie przypisania ref, ponieważ jest to zmienna tylko do odczytu
  • CS8337: Pierwszy parametr metody rozszerzenia "ref" musi być typem wartości lub typem ogólnym ograniczonym do struktury.
  • CS8338: Pierwszy parametr "in" lub "ref readonly" metody rozszerzenia musi być konkretnym (niegeneryjnym) typem wartości.
  • CS8373: Lewa strona przypisania ref musi być zmienną typu ref.
  • CS8388: out Nie można zadeklarować zmiennej jako zmiennej lokalnej ref
  • CS8977: Nie można użyć ciągu "ref", "in" lub "out" w podpisie metody przypisanej za pomocą polecenia "UnmanagedCallersOnly".
  • CS8986: Modyfikator "scoped" parametru nie jest zgodny z elementem docelowym.
  • CS8987: Modyfikator "ograniczony zakres" parametru nie jest zgodny z przesłoniętym lub implementowanym składnikiem.
  • CS9061: Modyfikator "o określonym zakresie" nie może być używany z operacją 'discard'.
  • CS9062: Typy i aliasy nie mogą mieć nazwy "scoped".
  • CS9063: Nie można zastosować atrybutu UnscopedRefAttribute do tego parametru, ponieważ jest on domyślnie niezakresowy.
  • CS9065: Nie używaj elementu "System.Runtime.CompilerServices.ScopedRefAttribute". Zamiast tego użyj słowa kluczowego "scoped".
  • CS9066: Nie można zastosować atrybutu UnscopedRefAttribute do parametrów, które mają modyfikator o zakresie.
  • CS9072: Zmienna dekonstrukcji nie może być zadeklarowana jako lokalna zmienna ref
  • CS9101: UnscopedRefAttribute można stosować tylko do metod i właściwości wystąpienia struktury lub interfejsu wirtualnego i nie można ich stosować do konstruktorów lub elementów członkowskich tylko do inicjowania.
  • CS9102: Nie można zastosować atrybutu UnscopedRefAttribute do implementacji interfejsu, ponieważ zaimplementowany element członkowski nie ma tego atrybutu.
  • CS9104: Zasób instrukcji typu using nie może być używany w metodach async ani wyrażeniach lambda async.
  • CS9190: readonly modyfikator musi być określony po ref.
  • CS9199: ref readonly Parametr nie może mieć atrybutu Out.

Podczas nieprawidłowego użycia zmiennych referencyjnych są generowane następujące ostrzeżenia:

  • CS9073: Modyfikator "o określonym zakresie" parametru nie jest zgodny z elementem docelowym.
  • CS9074: Modyfikator "o określonym zakresie" parametru nie pasuje do przesłonięcia ani zaimplementowanego elementu członkowskiego.
  • CS9191: ref Modyfikator argumentu odpowiadającego in parametrowi jest odpowiednikiem parametru in. Rozważ użycie in zamiast tego.
  • CS9192: Argument należy przekazać za pomocą słowa kluczowego ref lub in.
  • CS9193: Argument powinien być zmienną, ponieważ jest przekazywany do parametru ref readonly
  • CS9195: Argument powinien zostać przekazany za pomocą słowa kluczowego in
  • CS9196: Modyfikator rodzaju referencji parametru nie jest zgodny z odpowiednim parametrem w przesłoniętej lub implementowanej składowej.
  • CS9197: Modyfikator rodzaju odwołania parametru nie pasuje do odpowiedniego parametru w ukrytym elemencie członkowskim.
  • CS9198: Modyfikator rodzaju odwołania parametru nie pasuje do odpowiedniego parametru w elemencie docelowym.
  • CS9200: wartość domyślna jest określana dla ref readonly parametru, ale ref readonly powinna być używana tylko w przypadku odwołań. Rozważ zadeklarowanie parametru jako in.
  • CS9201: Pole ref powinno mieć przypisane odwołanie przed użyciem.
  • CS9265: Pole nigdy nie jest przypisywane przez ref i zawsze będzie mieć wartość domyślną (odwołanie o wartości null)

Te błędy i ostrzeżenia są zgodne z następującymi motywami:

W tym artykule termin zmienna referencyjna jest używany jako ogólne określenie parametru zadeklarowanego z użyciem jednego z modyfikatorów in, ref readonly, ref lub out, albo zmiennej lokalnej ref, pola ref w elemencie ref struct lub wartości zwracanej ref. Zmienna referencyjna odwołuje się do innej zmiennej, zwanej referentem.

Nieprawidłowa składnia

Te błędy wskazują, że używasz nieprawidłowej składni dotyczącej zmiennych referencyjnych:

  • CS8373: Lewa strona przypisania ref musi być zmienną typu ref.
  • CS8388: Zmienna out nie może być zadeklarowana jako zmienna lokalna ref.
  • CS9190: readonly modyfikator musi być określony po ref.

Aby naprawić te błędy:

  • Upewnij się, że lewy operand = ref operatora jest zmienną referencyjną, a nie wyrażeniem wartościowym lub zmienną lokalną bez odwołania. Przypisanie odwołania wymaga, aby obie strony były zmiennymi odwołań, które mogą utworzyć alias w tej samej lokalizacji pamięci (CS8373).
  • Podczas deklarowania parametrów odwołania należy zapisać modyfikator jako ref readonly zamiast readonly ref. Specyfikacja języka C# wymaga, aby słowo kluczowe ref poprzedzało modyfikator readonly w deklaracjach parametrów, aby zachować spójną składnię we wszystkich typach parametrów referencyjnych (CS9190).
  • Użyj słowa kluczowego ref zamiast out podczas deklarowania lokalnych zmiennych referencyjnych. out jest wyłącznie modyfikatorem parametrów, który wskazuje, że metoda musi przypisać wartość przed zwróceniem, natomiast ref jest odpowiednim słowem kluczowym do tworzenia zmiennych lokalnych, które aliasują inne lokalizacje magazynu (CS8388). Aby uzyskać więcej informacji na temat zmiennych referencyjnych i ich wymagań składniowych, zobacz zmienne referencyjne i specyfikacja języka C#.

Ograniczenia zmiennych referencyjnych

Poniższe błędy wskazują, że nie można użyć zmiennej referencyjnej w miejscu, w którym się jej używa:

  • CS0631: ref i out nie są prawidłowe w tym kontekście
  • CS0767: Nie można dziedziczyć z interfejsu z określonymi parametrami typu, ponieważ powodowałoby to, że metoda zawierałaby przeciążenia, które różnią się tylko pod względem ref i out
  • CS1623: Iteratory nie mogą mieć parametrów ref, in ani out
  • CS1741: Parametr ref lub out nie może mieć wartości domyślnej
  • CS1939: Nie można przekazać zmiennej zakresu jako parametru out lub ref
  • CS1988: Metody asynchroniczne nie mogą mieć parametrów ref, in ani out
  • CS7084: Zdarzenie środowiska uruchomieniowego systemu Windows nie może zostać przekazane jako parametr out lub ref.
  • CS8196: Odwołanie do niejawnie typizowanej out zmiennej nie jest dozwolone na tej samej liście argumentów.
  • CS8325: "await" nie może być używany w wyrażeniu zawierającym operator warunkowy ref
  • CS8326: Oba wartości operatorów warunkowych muszą być wartościami ref lub żadna z nich nie może być wartością ref
  • CS8327: Wyrażenie musi być poprawne, aby było zgodne z alternatywną wartością ref
  • CS8337: Pierwszy parametr metody rozszerzenia "ref" musi być typem wartości lub typem ogólnym ograniczonym do struktury.
  • CS8338: Pierwszy parametr "in" lub "ref readonly" metody rozszerzenia musi być konkretnym (niegeneryjnym) typem wartości.
  • CS8977: Nie można użyć ciągu "ref", "in" lub "out" w podpisie metody przypisanej za pomocą polecenia "UnmanagedCallersOnly".
  • CS9072: Zmienna dekonstrukcji nie może być zadeklarowana jako lokalna zmienna ref
  • CS9104: using Zasób instrukcji typu nie może być używany w metodach asynchronicznych ani asynchronicznych wyrażeniach lambda.
  • CS9199: ref readonly Parametr nie może mieć atrybutu Out.

Następujące ostrzeżenia wskazują, że zmienna referencyjna nie powinna być używana i może być niebezpieczna:

  • CS9196: Modyfikator rodzaju odwołania parametru nie pasuje do odpowiedniego parametru w zastąpieniu ani zaimplementowaniu elementu członkowskiego.
  • CS9197: Modyfikator rodzaju odwołania parametru nie pasuje do odpowiedniego parametru w ukrytym elemencie członkowskim.
  • CS9198: Modyfikator rodzaju odwołania parametru nie pasuje do odpowiedniego parametru w elemencie docelowym.
  • CS9200: wartość domyślna jest określana dla ref readonly parametru, ale ref readonly powinna być używana tylko w przypadku odwołań. Rozważ zadeklarowanie parametru jako in.
  • CS9201: Przed użyciem należy przypisać pole ref.
  • CS9265: Pole nigdy nie jest przypisywane przez ref i zawsze będzie miało wartość domyślną (odwołanie o wartości null)

Aby naprawić te błędy:

  • Usuń parametry odwołania z indeksatorów. Indeksatory zostały zaprojektowane tak, aby zapewnić składnię dostępu przypominającą tablicę, a kompilator nie może zagwarantować bezpiecznego śledzenia okresu istnienia odwołań przekazywanych przez metody dostępu indeksatora (CS0631, CS1623).
  • Usuń parametry odwołania z metod iteratora. Iteratory wykonują kod w leniwy sposób przez wiele wywołań, używając maszyn stanu, a kompilator nie może zagwarantować, że odwoływane zmienne zachowają ważność na granicach yield, gdzie wykonywanie jest zawieszone i wznawiane (CS1623).
  • Usuń parametry odwołania z metod asynchronicznych. Metody asynchroniczne mogą wstrzymać wykonywanie w punktach await i wznowić je na innych wątkach, co uniemożliwia zagwarantowanie, że odwołania do zmiennych pozostaną prawidłowe i dostępne w trakcie wykonywania metody (CS1988).
  • Unikaj używania wyrażeń await wewnątrz wyrażeń warunkowych ref. Operacja await może zawiesić wykonywanie i unieważnić odwołania wybrane przez operatora warunkowego, co prowadzi do potencjalnego użycia unieważnionych odwołań podczas wznawiania wykonywania (CS8325).
  • Upewnij się, że obie gałęzie operatora warunkowego ref zwracają odwołania lub żadna nie zwraca odwołania, a jeśli oba zwracają odwołania, muszą być tego samego typu. Operator warunkowy musi wygenerować spójny typ wyniku, który może być bezpiecznie używany przez kod wywołujący niezależnie od wybranej gałęzi (CS8326, CS8327).
  • Usuń wartości domyślne z parametrów ref i out. Parametry odwołania należy zawsze podać w lokacji wywołania, aby ustanowić wymaganą relację aliasu między parametrem a istniejącą zmienną, co sprawia, że wartości domyślne są semantycznie bez znaczenia (CS1741).
  • Unikaj deklarowania niejawnie typizowanej out zmiennej na liście argumentów, która również odwołuje się do tej samej zmiennej. Kompilator musi wywnioskować typ zmiennej z podpisu metody, a jednocześnie weryfikować użycie tej zmiennej w tym samym wyrażeniu, tworząc zależność cykliczną (CS8196).
  • Nie przekazuj zmiennych zakresu zapytań LINQ jako parametrów referencyjnych. Zmienne zakresu to zmienne iteracji generowane przez kompilator, których okres istnienia jest zarządzany przez model wykonywania zapytania i nie ma stabilnych lokalizacji pamięci, do których można bezpiecznie odwoływać się (CS1939).
  • Użyj zmiennych wartości regularnych zamiast zmiennych lokalnych ref podczas dekonstrukcji obiektów. Dekonstrukcja tworzy nowe zmienne do przyjmowania zdekonstrukowanych wartości, a zmienne referencyjne próbują utworzyć alias tych tymczasowych wartości, zamiast przechowywać je niezależnie (CS9072).
  • Unikaj implementowania wielu interfejsów, w których metody różnią się tylko modyfikatorem ref w porównaniu do out na parametrach. Specyfikacja języka C# traktuje je jako odrębne podpisy, ale nie zapewnia sposobu na rozróżnienie, którą implementację wywołać, ponieważ zarówno ref, jak i out współdzielą taką samą składnię wywołania na granicach implementacji (CS0767).
  • Usuń parametry odwołania z metod oznaczonych za pomocą System.Runtime.InteropServices.UnmanagedCallersOnlyAttribute polecenia. Te metody są wywoływane z niezarządzanego kodu, który nie rozumie reguł bezpieczeństwa odwołań w języku C#i nie może zagwarantować prawidłowego zarządzania okresami istnienia odwołanych zmiennych w granicach zarządzanych/niezarządzanych (CS8977).
  • ref Użyj modyfikatora w metodzie rozszerzenia pierwszych parametrów tylko dla typów wartości lub typów ogólnych ograniczonych do typów wartości. Typy referencyjne są już przekazywane przez odwołanie na poziomie CLR, a dodanie ref stworzyłoby odwołanie do odwołania, natomiast rozszerzenia typów wartości z użyciem ref umożliwiają mutację rozszerzonego wystąpienia (CS8337, CS8338).
  • Nie przekazuj zdarzeń środowiska uruchomieniowego systemu Windows jako parametrów referencyjnych. Te zdarzenia są zgodne z systemem typów środowiska uruchomieniowego środowisko wykonawcze systemu Windows, który ma inny cykl życia i semantykę dotyczącą wątków niż odwołania platformy .NET i nie obsługuje zachowania aliasowania wymaganego przez parametry odwołań w języku C# (CS7084).
  • Usuń parametr System.Runtime.InteropServices.OutAttribute z ref readonly parametrów. Ten atrybut jest przeznaczony do przetwarzania semantyki w scenariuszach wywołań platformy, w których kierunek parametru jest wyłącznie wychodzący, co powoduje konflikt z gwarancją ref readonly , że parametr odwołuje się do istniejących danych, które nie zostaną ponownie przydzielone (CS9199).
  • Upewnij się, że wszystkie ref pola w typie są przypisywane podczas inicjalizacji pól lub we wszystkich ścieżkach kodu konstruktora przed jego zakończeniem. Niezainicjowane pola ref zawierają nieprawidłowe odwołania, które mogą prowadzić do uszkodzenia pamięci w przypadku uzyskania dostępu (CS9201, CS9265).
  • Dopasuj modyfikatory rodzaju odwołania (ref, in, out, ref readonly) między metodą a jej zastąpioną metodą bazową lub zaimplementowaną metodą interfejsu. Modyfikator odwołania jest częścią kontraktu sygnatury metody, który typy pochodne muszą przestrzegać, aby zachować zastępowalność i oczekiwania wywołującego (CS9196, CS9197, CS9198).
  • Zadeklaruj parametry jako in, zamiast ref readonly podczas podawania wartości domyślnych. ref readonly jest przeznaczony dla scenariuszy, w których obiekt wywołujący przekazuje odwołanie do istniejącej zmiennej, podczas gdy in parametry mogą akceptować zarówno odwołania, jak i tymczasowe kopie wartości, co czyni wartości domyślne zrozumiałymi (CS9200).

Aby uzyskać więcej informacji o tym, gdzie są dozwolone zmienne referencyjne, zobacz Parametry metody, Iteratory, Wzorce programowania asynchronicznego i Specyfikacja języka C#.

unscoped ref Ograniczenia

Kwalifikator unscoped przy parametrach ref nie jest dozwolony w niektórych miejscach:

  • CS9101: UnscopedRefAttribute można stosować tylko do metod instancji struktur lub interfejsu wirtualnego i właściwości, i nie można ich stosować do konstruktorów lub składników tylko do inicjowania.
  • CS9102: Nie można zastosować atrybutu UnscopedRefAttribute do implementacji interfejsu, ponieważ zaimplementowany element członkowski nie ma tego atrybutu.

Aby naprawić te błędy:

  • Usuń modyfikator unscoped lub atrybut System.Diagnostics.CodeAnalysis.UnscopedRefAttribute z konstruktorów struktur i członków tylko do inicjalizacji. Te elementy członkowskie mają specjalną semantykę inicjalizacji, w której kompilator musi zapewnić, że żadne odwołania nie przetrwają fazy inicjalizacji, a zezwolenie na odwołania niezakresowe narusza gwarancję, że inicjalizacja zostanie ukończona, zanim struktura stanie się w pełni dostępna (CS9101).
  • unscoped Usuń modyfikator z metod implementacji interfejsu, gdy odpowiednia metoda interfejsu jej nie ma. Niezakresowa cecha wpływa na kontrakt metody w odniesieniu do gwarancji okresu istnienia odwołań, a implementacje muszą zachować ten sam kontrakt co implementowany interfejs, aby zapewnić, że wywołujący mogą polegać na spójnym zachowaniu okresu istnienia niezależnie od tego, która implementacja jest wywoływana (CS9102).

Aby uzyskać więcej informacji na temat referencji z zakresem i bez zakresu, zobacz sekcje Parametry metody i Ograniczenie bezpiecznego kontekstu w specyfikacji języka C#.

Zmienne referencyjne wymagają obiektu referencyjnego

Należy podać zmienną jako argument parametru referencyjnego, wartości zwracanej przez referencję lub lokalnego przypisania ref:

  • CS0206: Nie można użyć właściwości ani indeksatora, które nie zwracają przez odwołanie, jako wartości out lub ref
  • CS1510: Wartość ref lub out musi być zmienną z możliwością przypisania

Ostrzeżenia:

  • CS9191: ref Modyfikator argumentu odpowiadającego in parametrowi jest odpowiednikiem parametru in. Rozważ użycie in zamiast tego.
  • CS9192: Argument powinien być przekazywany z użyciem słowa kluczowego ref lub in.
  • CS9193: Argument powinien być zmienną, ponieważ jest przekazywany do parametru ref readonly
  • CS9195: Argument powinien zostać przekazany za pomocą słowa kluczowego in

Aby naprawić te błędy:

  • Przechowuj wynik dostępu do właściwości lub indeksatora w zmiennej lokalnej przed przekazaniem go jako parametru odwołania. Właściwości i indeksatory to metody, które zwracają wartości, a nie zapewniają bezpośredniego dostępu do lokalizacji przechowywania, a parametry referencyjne wymagają rzeczywistej zmiennej ze stabilną lokalizacją pamięci, która może być aliasowana (CS0206, CS1510).
  • in Użyj modyfikatora zamiast ref podczas przekazywania argumentów do in parametrów. Chociaż ref technicznie działa ze względu na zgodność z poprzednimi wersjami, in modyfikator wyraźniej wyraża intencję, że argument jest tylko do odczytu i może być przekazywany wydajniej jako odwołanie bez kopiowania (CS9191, CS9195).
  • Dodaj odpowiedni modyfikator odwołań (ref, in, lub ref readonly) podczas przekazywania argumentów do parametrów, które oczekują odwołań. Pominięcie modyfikatora może spowodować utworzenie tymczasowej kopii wartości przez kompilator, co jest nieefektywne i może prowadzić do nieoczekiwanego zachowania, jeśli kod wywołujący oczekuje modyfikacji w oryginalnej zmiennej (CS9192, CS9193).

Aby uzyskać więcej informacji na temat parametrów referencyjnych i przekazywania zmiennych według odwołania, zobacz Parametry metody, słowo kluczowe ref i specyfikacja języka C#.

Zapisywalne zmienne referencyjne wymagają zapisywalnego obiektu docelowego

Zapisywalna zmienna referencyjna wymaga, aby obiekt, do którego się odnosi, również był zapisywalny. Następujące błędy wskazują, że zmienna nie jest zapisywalna:

  • CS0192: Pole readonly nie może być używane jako wartość ref lub out (z wyjątkiem konstruktora)
  • CS0199: Pole static readonly nie może być używane jako wartość ref lub out (z wyjątkiem konstruktora statycznego)
  • CS1605: Nie można użyć zmiennej jako wartości ref lub out, ponieważ jest tylko do odczytu
  • CS1649: Elementy pola readonly nie mogą być używane jako wartość ref lub out (z wyjątkiem konstruktora)
  • CS1651: Pola pola static readonly nie mogą być używane jako wartość ref lub out (z wyjątkiem konstruktora statycznego)
  • CS1655: Nie można używać pól typu jako wartości ref lub out
  • CS1657: Nie można użyć zmiennej jako wartości ref lub out
  • CS8329: Nie można użyć zmiennej jako wartości ref lub out, ponieważ jest to zmienna readonly
  • CS8330: Składowe zmiennej nie mogą być używane jako wartość ref lub out, ponieważ jest to zmienna tylko do odczytu
  • CS8331: Nie można przypisać wartości do zmiennej ani użyć jej po prawej stronie przypisania ref, ponieważ jest to zmienna tylko do odczytu
  • CS8332: Nie można przypisać wartości do składowej zmiennej ani użyć jej po prawej stronie przypisania ref, ponieważ jest to zmienna tylko do odczytu

Aby naprawić te błędy:

  • Skopiuj wartość z pola tylko do odczytu do zmiennej lokalnej i przekaż tę zmienną lokalną jako parametr ref lub out. Pola tylko do odczytu są niezmienne po zainicjowaniu, z wyjątkiem w konstruktorach, i odwołania zapisywalne do nich naruszałyby gwarancję niezmienności, jaką zapewnia readonly (CS0192, CS0199, CS1649, CS1651).
  • Użyj parametrów ref readonly lub in zamiast ref lub out, gdy musisz przekazać zmienne tylko do odczytu, zmienne iteracyjne lub inne wartości niemodyfikowalne według odwołania. Modyfikatory te wskazują, że metoda odczytuje tylko przywołyną wartość bez próby jej zmodyfikowania. Jest to zgodne z ograniczeniami niezmienności oryginalnej zmiennej (CS1605, CS1655, CS1657, CS8329).
  • Skopiuj elementy członkowskie zmiennych readonly do zmiennych lokalnych przed przekazaniem ich jako odwołań zapisywalnych. Mimo że sam element członkowski może nie być zadeklarowany jako tylko do odczytu, jest on dostępny za pośrednictwem ścieżki tylko do odczytu (za pośrednictwem pola tylko do odczytu, parametru in lub lokalnego ref readonly), a kompilator wymusza przechodniość właściwości tylko do odczytu, aby zapobiec pośredniej mutacji danych tylko do odczytu (CS8330, CS8332).
  • Unikaj zapisywalnych przypisań ref w celu odczytu zmiennych, zmiennych iteracji foreach, przy użyciu zasobów instrukcji lub zmiennych stałych instrukcji. Te zmienne mają specjalne semantyki okresu istnienia zarządzane przez kompilator. Zmienna jest automatycznie finalizowana lub usuwana na końcu zakresu. Zewnętrzne referencje tworzą wiszące referencje po usunięciu (CS8331).

Aby uzyskać więcej informacji na temat semantyki readonly i parametrów referencyjnych, zobacz słowo kluczowe readonly, modyfikator parametru in, ref readonly i specyfikację języka C#.