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:
readonly
Nie można użyć pola jakoref
wartości lubout
(z wyjątkiem konstruktora) - CS0199:
static readonly
Nie można użyć pola jakoref
wartości lubout
(z wyjątkiem konstruktora statycznego) - CS0206: Nie zwracana właściwość lub indeksator nie może być używana jako
out
wartość lubref
- CS0631:
ref
iout
nie są prawidłowe w tym kontekście - CS0767: Nie można dziedziczyć interfejsu z określonymi parametrami typu, ponieważ powoduje, że metoda zawiera przeciążenia, które różnią się tylko na i
ref
out
- CS1510: Wartość
ref
lubout
musi być zmienną z możliwością przypisania - CS1605: Nie można użyć zmiennej
ref
jako wartości lubout
, ponieważ jest ona tylko do odczytu - CS1623: Iteratory nie mogą mieć
ref
parametrów ,in
aniout
- CS1649: Składowe
readonly
pola nie mogą być używane jakoref
wartość lubout
(z wyjątkiem konstruktora) - CS1651: Pola statycznego pola readonly nie mogą być używane jako
ref
wartość lubout
(z wyjątkiem konstruktora statycznego) - CS1655: Nie można użyć pól typu jako
ref
wartości lubout
- CS1657: Nie można użyć zmiennej
ref
jako wartości lubout
- CS1741: Parametr lub
out
ref
nie może mieć wartości domyślnej - CS1939: Nie można przekazać zmiennej zakresu jako parametru
out
lubref
- CS1988: Metody asynchroniczne nie mogą mieć
ref
parametrów ,in
lubout
- CS7084: Zdarzenie środowisko wykonawcze systemu Windows może nie zostać przekazane jako
out
parametr lubref
. - CS8166: Nie można zwrócić parametru przez odwołanie, ponieważ nie
ref
jest to parametr - CS8167: Nie można zwrócić przez odwołanie do elementu członkowskiego parametru, ponieważ nie
ref
jest to parametr lubout
- CS8168: Nie można zwrócić lokalnego przez odwołanie, ponieważ nie jest to lokalne odwołanie
- CS8169: Nie można zwrócić elementu członkowskiego zmiennej lokalnej przez odwołanie, ponieważ nie jest to element lokalny 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 warunkowyref
- 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
ref
jako wartości lubout
, ponieważ jest to zmienna readonly - CS8330: Składowe zmiennej nie mogą być używane jako
ref
wartość lubout
, ponieważ jest to zmienna readonly - CS8331: Nie można przypisać do zmiennej ani użyć jej jako prawej strony
ref
przypisania, ponieważ jest to zmienna readonly - CS8332: Nie można przypisać do elementu członkowskiego zmiennej lub użyć go jako prawej strony
ref
przypisania, ponieważ jest to zmienna readonly - 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. - CS8351: Gałęzie operatora warunkowego
ref
nie mogą odwoływać się do zmiennych z niezgodnymi zakresami deklaracji - CS8373: Lewa strona
ref
przypisania musi być zmienną ref. - CS8374: Nie można przypisać źródła ref-assign ma węższy zakres ucieczki niż miejsce docelowe.
- 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". - CS9072: Zmienna dekonstrukcji nie może być zadeklarowana jako lokalna zmienna ref
- CS9077: Nie można zwrócić parametru za pomocą odwołania za pośrednictwem parametru
ref
; można go zwrócić tylko w instrukcji return - CS9078: Nie można zwrócić przez odwołanie do elementu członkowskiego parametru za pomocą parametru
ref
; można go zwrócić tylko w instrukcji return - CS9079: Nie można przypisać odwołania, ponieważ źródło może uniknąć bieżącej metody tylko za pomocą instrukcji return.
- CS9096: Nie można przypisać odwołania, ponieważ źródło ma szerszy zakres ucieczki wartości niż miejsce docelowe zezwalające na przypisanie za pośrednictwem źródła wartości z węższymi zakresami ucieczki niż miejsce docelowe.
- 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:
using
Zasób instrukcji typu nie może być używany w metodach asynchronicznych ani asynchronicznych wyrażeniach lambda. - CS9190:
readonly
modyfikator musi być określony poref
. - CS9199:
ref readonly
Parametr nie może mieć atrybutu Out.
Podczas nieprawidłowego użycia zmiennych referencyjnych są generowane następujące ostrzeżenia:
- CS9085: Ta zmienna ref przypisuje, ale miejsce docelowe ma węższy zakres ucieczki niż źródło.
- CS9086: Gałęzie operatora warunkowego
ref
odwołują się do zmiennych z niezgodnymi zakresami deklaracji - CS9087: Zwraca parametr według odwołania, ale nie jest parametrem
ref
- CS9089: Zwraca to odwołanie do elementu członkowskiego parametru, który nie jest parametrem
ref
lubout
- CS9091: Zwraca wartość lokalną przez odwołanie, ale nie jest to lokalne odwołanie
- CS9092: Zwraca element członkowski lokalnego przez odwołanie, ale nie jest to element lokalny ref
- CS9093: ten ref-assigns, ale źródło może uciec od bieżącej metody tylko za pomocą instrukcji return.
- CS9094: Zwraca parametr przez odwołanie za pośrednictwem parametru
ref
, ale można go bezpiecznie zwrócić tylko w instrukcji return - CS9095: Zwraca to odwołanie do elementu członkowskiego parametru za pomocą parametru
ref
, ale można go bezpiecznie zwrócić tylko w instrukcji return - CS9097: Ten ref-assigns, ale źródło ma szerszy zakres ucieczki wartości niż miejsce docelowe zezwalające na przypisanie za pośrednictwem miejsca docelowego wartości z węższymi zakresami ucieczki niż źródło.
- CS9191:
ref
Modyfikator argumentu odpowiadającegoin
parametrowi jest odpowiednikiem parametruin
. Rozważ użyciein
zamiast tego. - CS9192: Argument powinien być przekazywany za pomocą
ref
słowa kluczowego 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 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, aleref readonly
powinna być używana tylko w przypadku odwołań. Rozważ zadeklarowanie parametru jakoin
. - CS9201: Przed użyciem należy przypisać pole ref.
- CS9265: Pole nigdy nie jest przypisane do wartości domyślnej (odwołanie o wartości null)
Te błędy i ostrzeżenia są zgodne z następującymi motywami:
- Nieprawidłowa składnia: Składnia deklaracji lub użycia jest nieprawidłowa.
- Konstrukcje językowe, w których
ref
zmienne są nieprawidłowe: niektóre idiomy języka C# nie zezwalają na zmienne. Zwykle jest to spowodowane tym, że nie można niezawodnie przeprowadzić analizy bezpieczeństwa ref. - Wyrażenie wartości używane w przypadku, gdy wymagana jest zmienna referencyjna: wyrażenie używane jako zmienna referencyjna musi być zmienną, a nie wyrażeniem wartości.
- Zmienne referencyjne z możliwością zapisu odwołujące się do zmiennych odczytu: odwołanie do zmiennej readonly nie może być przekazywane przez odwołanie do zapisu.
- naruszenia bezpieczeństwa ref: zmienna referencyjna nie może odwoływać się do zmiennej, która ma węższy kontekst. Oznaczałoby to, że zmienna referencyjna może odwoływać się do nieprawidłowej pamięci.
W tym artykule użyto zmiennej referencyjnej terminu jako ogólnego terminu dla parametru zadeklarowanego przy użyciu jednego z in
modyfikatorów , ref
ref readonly
, lub ref
out
zmiennej lokalnej, ref
pola w ref struct
obiekcie lub zwracaniaref
. Zmienna referencyjna odwołuje się do innej zmiennej nazywanej odwołaniem.
Nieprawidłowa składnia
Te błędy wskazują, że używasz nieprawidłowej składni dotyczącej zmiennych referencyjnych:
- CS8373: Lewa strona
ref
przypisania musi być zmienną ref. - CS8388: Zmienna
out
nie może być zadeklarowana jako lokalna nazwa ref. - CS9190:
readonly
modyfikator musi być określony poref
.
Możesz poprawić błąd z jedną z następujących zmian:
- Lewy operand
= ref
operatora musi być zmienną referencyjną. Aby uzyskać więcej informacji na temat poprawnej składni, zobacz zmienne referencyjne. - Modyfikator
ref readonly
parametrów musi być w tej kolejności.readonly ref
nie jest modyfikatorem parametrów prawnych. Przełącz kolejność wyrazów. - Nie można zadeklarować zmiennej lokalnej jako
out
. Aby zadeklarować lokalną zmienną referencyjną, użyj poleceniaref
.
Ograniczenia zmiennych referencyjnych
Następujące błędy wskazują, że nie można użyć zmiennej referencyjnej, w której istnieje:
- CS0631:
ref
iout
nie są prawidłowe w tym kontekście - CS0767: Nie można dziedziczyć interfejsu z określonymi parametrami typu, ponieważ powoduje, że metoda zawiera przeciążenia, które różnią się tylko na i
ref
out
- CS1623: Iteratory nie mogą mieć
ref
parametrów ,in
aniout
- CS1741: Parametr lub
out
ref
nie może mieć wartości domyślnej - CS1939: Nie można przekazać zmiennej zakresu jako parametru
out
lubref
- CS1988: Metody asynchroniczne nie mogą mieć
ref
parametrów ,in
lubout
- CS7084: Zdarzenie środowisko wykonawcze systemu Windows może nie zostać przekazane jako
out
parametr lubref
. - 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, aleref readonly
powinna być używana tylko w przypadku odwołań. Rozważ zadeklarowanie parametru jakoin
. - CS9201: Przed użyciem należy przypisać pole ref.
- CS9265: Pole nigdy nie jest przypisane do wartości domyślnej (odwołanie o wartości null)
Aby naprawić błąd, usuń zmienną referencyjną, w której nie jest dozwolona:
- Usuń
in
parametry ,ref
iout
z indeksatorów, iteratorów i metod asynchronicznych. - Usuń wyrażenia warunkowe ref (
? :
), które zawierają oczekiwanie. ref
Usuń modyfikator z pierwszego parametru metody rozszerzenia, w której ten typ nie jest typem wartości lub typem ogólnym ograniczonym jako typ wartości.- Albo oba wyrażenia operatora warunkowego nie muszą być
ref
zmiennymi. Usuńref
z jednego wyrażenia lub dodaj je do drugiego. Jeśli jestref
to wyrażenie warunkowe, oba wyrażenia muszą być tego samego typu. ref
parametry iout
nie mogą mieć wartości domyślnych. Usuńref
out
lub modyfikator lub usuń wartość domyślną.- Niejawnie typizowanej
out
deklaracji zmiennej nie można również wyświetlić w innym miejscu na tej samej liście argumentów. - Nie można umieścić zmiennych referencyjnych w instrukcji w
using
async
wyrażeniach lambda metod. - Zmienna zakresu w wyrażeniu zapytania LINQ nie może być przekazywana przez odwołanie.
- Nie można zdekonstruować obiektu do zmiennych referencyjnych. Zastąp zmienne referencyjne zmiennymi wartości.
- Nie można zaimplementować wielu interfejsów, w których przeciążenia metody różnią się tylko w systemach
ref
iout
. Na przykład jeden interfejs deklarujevoid M(ref int i)
, a inny interfejs deklarujevoid M(out int i)
wartość . Klasa nie może zaimplementować obu interfejsów, ponieważ metody nie są rozróżnialne. Można zaimplementować tylko jeden z tych interfejsów. - Metody przypisywane za pomocą System.Runtime.InteropServices.UnmanagedCallersOnlyAttribute parametrów referencyjnych nie mogą być używane.
- Nie można przekazać zdarzenia środowiska uruchomieniowego systemu Windows jako zmiennej referencyjnej.
- Parametr
ref readonly
nie może mieć zastosowanego System.Runtime.InteropServices.OutAttribute do niego w interfejsie API komunikacji zdalnie. - Zainicjuj
ref
pole w konstruktorze lub jako inicjator pola.
unscoped ref
Ograniczenia
Kwalifikator unscoped
parametrów ref
nie jest dozwolony w niektórych lokalizacjach:
- CS9101: UnscopedRefAttribute można stosować tylko do wystąpienia struktury lub metod interfejsu wirtualnego i właściwości, i nie można ich stosować do konstruktorów lub elementów członkowskich tylko inicjowania.
- CS9102: Nie można zastosować atrybutu UnscopedRefAttribute do implementacji interfejsu, ponieważ zaimplementowany element członkowski nie ma tego atrybutu.
Należy usunąć unscoped
modyfikator w deklaracji parametru, która spowodowała błąd.
Zmienne referencyjne wymagają odwołania
Należy podać zmienną jako argument do parametru referencyjnego, zwrotu odwołania lub przypisania lokalnego ref:
- CS0206: Nie zwracana właściwość lub indeksator nie może być używana jako
out
wartość lubref
- CS1510: Wartość
ref
lubout
musi być zmienną z możliwością przypisania
Ostrzeżenia:
- CS9191:
ref
Modyfikator argumentu odpowiadającegoin
parametrowi jest odpowiednikiem parametruin
. Rozważ użyciein
zamiast tego. - CS9192: Argument powinien być przekazywany za pomocą
ref
słowa kluczowego 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
Kompilator emituje te błędy podczas używania wyrażenia, które oblicza wartość, w której należy użyć zmiennej. Aby używać tego wyrażenia, musisz przechowywać wynik tego wyrażenia w zmiennej. Na przykład właściwości i indeksatory zwracają wartości, a nie zmienne. Wynik należy zapisać w zmiennej i przekazać odwołanie do tej zmiennej.
Zmienne referencyjne z możliwością zapisu wymagają odwołania z możliwością zapisu
Zapisywalna zmienna referencyjna wymaga, aby odwołanie było również możliwe do zapisu. Następujące błędy wskazują, że zmienna nie jest zapisywalna:
- CS0192:
readonly
Nie można użyć pola jakoref
wartości lubout
(z wyjątkiem konstruktora) - CS0199:
static readonly
Nie można użyć pola jakoref
wartości lubout
(z wyjątkiem konstruktora statycznego) - CS1605: Nie można użyć zmiennej
ref
jako wartości lubout
, ponieważ jest ona tylko do odczytu - CS1649: Składowe
readonly
pola nie mogą być używane jakoref
wartość lubout
(z wyjątkiem konstruktora) - CS1651: Pola
static readonly
pola pola nie mogą być używane jakoref
wartość lubout
(z wyjątkiem konstruktora statycznego) - CS1655: Nie można użyć pól typu jako
ref
wartości lubout
- CS1657: Nie można użyć zmiennej
ref
jako wartości lubout
- CS8329: Nie można użyć zmiennej
ref
jako wartości lubout
, ponieważ jest to zmienna readonly - CS8330: Składowe zmiennej nie mogą być używane jako
ref
wartość lubout
, ponieważ jest to zmienna readonly - CS8331: Nie można przypisać do zmiennej ani użyć jej jako prawej strony
ref
przypisania, ponieważ jest to zmienna readonly - CS8332: Nie można przypisać do elementu członkowskiego zmiennej lub użyć go jako prawej strony
ref
przypisania, ponieważ jest to zmienna readonly
Przykłady zmiennych, które nie są zapisywalne, obejmują:
- pola tylko do odczytu, zarówno wystąpienia, jak i pola statyczne.
readonly
Elementy członkowskie pól.- Zmienna
this
. - Zmienna iteracji foreach
- Używanie zmiennej lub zmiennej stałej.
Należy skopiować wartość i przekazać odwołanie do kopii.
Naruszenia bezpieczeństwa ref
Kompilator śledzi bezpieczny kontekst odwołań i zmiennych referencyjnych. Kompilator zgłasza błędy lub ostrzeżenia w niebezpiecznym kodzie, gdy zmienna referencyjna odwołuje się do zmiennej referencyjnej, która nie jest już prawidłowa. Odwołanie musi mieć bezpieczny kontekst, który jest co najmniej tak szeroki, jak kontekst bezpieczny ref zmiennej referencyjnej. Naruszenie tych kontroli bezpieczeństwa oznacza, że zmienna referencyjna uzyskuje dostęp do pamięci losowej zamiast zmiennej referencyjnej.
- CS8166: Nie można zwrócić parametru przez odwołanie, ponieważ nie
ref
jest to parametr - CS8167: Nie można zwrócić przez odwołanie do elementu członkowskiego parametru, ponieważ nie
ref
jest to parametr lubout
- CS8168: Nie można zwrócić lokalnego przez odwołanie, ponieważ nie jest to lokalne odwołanie
- CS8169: Nie można zwrócić elementu członkowskiego zmiennej lokalnej przez odwołanie, ponieważ nie jest to element lokalny ref
- CS8345: Właściwość pola lub zaimplementowana automatycznie nie może być typu, chyba że jest członkiem wystąpienia
ref struct
klasy . - CS8351: Gałęzie operatora warunkowego
ref
nie mogą odwoływać się do zmiennych z niezgodnymi zakresami deklaracji - CS8374: Nie można przypisać źródła ref-assign ma węższy zakres ucieczki niż miejsce docelowe.
- CS9077: Nie można zwrócić parametru za pomocą odwołania za pośrednictwem parametru
ref
; można go zwrócić tylko w instrukcji return - CS9078: Nie można zwrócić przez odwołanie do elementu członkowskiego parametru za pomocą parametru
ref
; można go zwrócić tylko w instrukcji return - CS9079: Nie można przypisać źródła ref-assign do miejsca docelowego, ponieważ źródło może uniknąć bieżącej metody tylko za pomocą instrukcji return.
- CS9096: Nie można przypisać źródła ref-assign do miejsca docelowego, ponieważ źródło ma szerszy zakres ucieczki wartości niż miejsce docelowe zezwalające na przypisanie za pośrednictwem lokalizacji docelowej wartości z węższymi zakresami ucieczki niż źródło.
Ostrzeżenia:
- CS9085: Ten element ref przypisuje źródło do miejsca docelowego, ale źródło ma węższy zakres ucieczki niż miejsce docelowe.
- CS9086: Gałęzie operatora warunkowego ref odwołują się do zmiennych z niezgodnymi zakresami deklaracji
- CS9087: Zwraca parametr według odwołania, ale nie jest parametrem
ref
- CS9089: Zwraca to odwołanie do elementu członkowskiego parametru, który nie jest parametrem
ref
lubout
- CS9091: Zwraca wartość lokalną przez odwołanie, ale nie jest to lokalne odwołanie
- CS9092: Zwraca element członkowski lokalnego przez odwołanie, ale nie jest to element lokalny ref
- CS9093: ten element ref przypisuje źródło do miejsca docelowego, ale źródło może uniknąć bieżącej metody tylko za pomocą instrukcji return.
- CS9094: Zwraca parametr przez odwołanie za pośrednictwem parametru
ref
, ale można go bezpiecznie zwrócić tylko w instrukcji return - CS9095: Zwraca to odwołanie do elementu członkowskiego parametru za pomocą parametru
ref
, ale można go bezpiecznie zwrócić tylko w instrukcji return - CS9097: Ten element ref przypisuje źródło do miejsca docelowego, ale źródło ma szerszy zakres ucieczki wartości niż miejsce docelowe zezwalające na przypisanie za pośrednictwem miejsca docelowego wartości z węższymi zakresami ucieczki niż źródło.
Kompilator używa analizy statycznej do określenia, czy odwołanie jest prawidłowe we wszystkich punktach, w których można użyć zmiennej referencyjnej. Należy refaktoryzować kod, aby odwołanie pozostaje prawidłowe we wszystkich lokalizacjach, w których zmienna referencyjna może się do niego odwoływać. Aby uzyskać szczegółowe informacje na temat reguł bezpieczeństwa ref, zobacz standard języka C# dotyczący kontekstów bezpiecznych ref.