Chyby a upozornění související s referenčními parametry, proměnnými a vráceními
Při práci s referenčními proměnnými je možné vygenerovat následující chyby:
- CS0192: Pole
readonly
nelze použít jakoref
hodnotu neboout
hodnotu (s výjimkou konstruktoru). - CS0199: Pole
static readonly
nelze použít jakoref
neboout
hodnotu (s výjimkou statického konstruktoru). - CS0206: Nevrací vlastnost nebo indexer nelze použít jako
out
neboref
hodnotu. - CS0631:
ref
aout
nejsou platné v tomto kontextu - CS0767: Nelze dědit rozhraní se zadanými parametry typu, protože způsobuje, že metoda obsahuje přetížení, které se liší pouze na
ref
aout
- CS1510: A
ref
neboout
hodnota musí být přiřaditelná proměnná. - CS1605: Proměnnou
ref
nelze použít jako hodnotu,out
protože je určena jen pro čtení - CS1623: Iterátory nemohou mít
ref
parametryin
neboout
- CS1649: Členy
readonly
pole nelze použít jakoref
hodnotu neboout
hodnotu (s výjimkou konstruktoru). - CS1651: Pole statického pole jen pro čtení nelze použít jako
ref
hodnotu neboout
hodnotu (s výjimkou statického konstruktoru). - CS1655: Nelze použít pole typu jako
ref
hodnotuout
- CS1657: Nelze použít proměnnou
ref
jako hodnotuout
- CS1741: A
ref
neboout
parametr nemůže mít výchozí hodnotu - CS1939: Proměnnou
out
rozsahu nelze předat jako parametrref
- CS1988: Asynchronní metody nemohou mít
ref
parametryin
neboout
- CS7084: Událost prostředí Windows Runtime nemusí být předána
out
jako neboref
parametr. - CS8166: Nelze vrátit parametr odkazem, protože se nejedná o
ref
parametr - CS8167: Nelze vrátit odkazem na člena parametru, protože se nejedná o
ref
parametrout
- CS8168: Nelze vrátit místní odkaz podle odkazu, protože se nejedná o odkaz na místní
- CS8169: Nelze vrátit člena místní proměnné odkazem, protože se nejedná o odkaz na místní
- CS8196: Odkaz na implicitně zapisovanou proměnnou není povolen ve stejném seznamu argumentů.
- CS8325: Výraz
await
obsahující podmíněnýref
operátor nelze použít. - CS8326: Obě hodnoty podmíněného operátoru musí být hodnoty ref nebo ani jedna z nich nesmí být hodnota ref.
- CS8327: Výraz musí být správný typ, aby odpovídal alternativní referenční hodnotě.
- CS8329: Proměnnou
ref
nelze použít jako hodnotu,out
protože se jedná o proměnnou jen pro čtení - CS8330: Členy proměnné nelze použít jako
ref
hodnotu,out
protože se jedná o proměnnou jen pro čtení. - CS8331: Nelze přiřadit proměnnou nebo ji použít jako pravou stranu
ref
přiřazení, protože se jedná o proměnnou jen pro čtení - CS8332: Nelze přiřadit členu proměnné nebo jej použít jako pravou stranu
ref
přiřazení, protože se jedná o proměnnou jen pro čtení - CS8337: První parametr metody rozšíření '
ref
' musí být typ hodnoty nebo obecný typ omezený na strukturu. - CS8338: První parametr "
in
' nebo 'ref readonly
' metody rozšíření musí být konkrétní (ne generický) typ hodnoty. - CS8351: Větve podmíněného operátoru
ref
nemohou odkazovat na proměnné s nekompatibilními obory deklarací - CS8373: Levá strana
ref
přiřazení musí být proměnnou odkazu. - CS8374: Zdroj nelze ref-assign má užší řídicí obor než cíl.
- CS8388: Proměnnou
out
nelze deklarovat jako místní odkaz. - CS8977: V podpisu metody s atributem UnmanagedCallersOnly nelze použít '
ref
', 'in
' nebo 'out
' - CS9072: Dekonstrukční proměnnou nelze deklarovat jako místní odkaz.
- CS9077: Nelze vrátit parametr odkazem prostřednictvím parametru
ref
; může být vrácen pouze v návratovém příkazu. - CS9078: Nelze vrátit odkazem na člena parametru prostřednictvím parametru
ref
; může být vrácen pouze v návratovém příkazu. - CS9079: Nelze ref-assign, protože zdroj může uniknout pouze aktuální metodu prostřednictvím příkazu return.
- CS9096: Nelze přiřadit odkaz, protože zdroj má širší řídicí obor hodnoty než cíl, který umožňuje přiřazení prostřednictvím zdroje hodnot s užšími řídicími obory než cíl.
- CS9101: UnscopedRefAttribute lze použít pouze na struktury nebo metody a vlastnosti instance virtuálního rozhraní a nelze jej použít u konstruktorů nebo inicializačních členů.
- CS9102: UnscopedRefAttribute nelze použít na implementaci rozhraní, protože implementovaný člen nemá tento atribut.
- CS9104: Prostředek
using
příkazu typu nelze použít v asynchronních metodách nebo asynchronních výrazech lambda. - CS9190:
readonly
Modifikátor musí být zadán zaref
. - CS9199: Parametr
ref readonly
nemůže mít atribut Out.
Při nesprávném použití referenčních proměnných se vygenerují následující upozornění:
- CS9085: Tento odkaz přiřadí proměnnou, ale cíl má užší řídicí obor než zdroj.
- CS9086: Větve podmíněného operátoru
ref
odkazují na proměnné s nekompatibilními obory deklarací. - CS9087: Vrátí parametr podle odkazu, ale nejedná se o
ref
parametr. - CS9089: Vrátí se odkazem na člena parametru, který není parametrem nebo
out
parametremref
. - CS9091: Vrátí místní hodnoty podle odkazu, ale nejedná se o odkaz na místní
- CS9092: Vrátí člena místního odkazu, ale nejedná se o odkaz na místní
- CS9093: Tento ref-assigns, ale zdroj může utéct pouze aktuální metodu příkazem return.
- CS9094: Vrátí parametr odkazem prostřednictvím parametru
ref
, ale může být vrácen pouze v příkazu return. - CS9095: Tato funkce vrátí odkazem na člena parametru prostřednictvím parametru
ref
, ale může být vrácena pouze v příkazu return. - CS9097: Tento odkaz přiřadí, ale zdroj má širší rozsah řídicích hodnot než cíl, který umožňuje přiřazení prostřednictvím cíle hodnot s užšími řídicími obory než zdroj.
- CS9191:
ref
Modifikátor argumentu odpovídajícíin
parametru je ekvivalentníin
. Místo toho zvažte použitíin
. - CS9192: Argument by měl být předán s klíčovým slovem nebo
in
s klíčovým slovemref
. - CS9193: Argument by měl být proměnnou, protože je předán parametru
ref readonly
. - CS9195: Argument by měl být předán s klíčovým slovem
in
- CS9196: Modifikátor druh odkazu parametru neodpovídá odpovídajícímu parametru v přepsání nebo implementovaném členu.
- CS9197: Modifikátor druh odkazu parametru neodpovídá odpovídajícímu parametru ve skrytém členu.
- CS9198: Modifikátor druh odkazu parametru neodpovídá odpovídajícímu parametru v cíli.
- CS9200: Pro parametr je zadána
ref readonly
výchozí hodnota, aleref readonly
měla by být použita pouze pro odkazy. Zvažte deklarování parametru jakoin
. - CS9201: Pole Odkaz by mělo být před použitím přiřazeno odkazem.
- CS9265: Pole není nikdy přiřazeno odkazem a vždy bude mít výchozí hodnotu (odkaz null)
Tyto chyby a upozornění se řídí těmito motivy:
- Nesprávná syntaxe: Syntaxe deklarace nebo použití je neplatná.
- Jazykové konstrukce, ve
ref
kterých nejsou proměnné platné: Některé idiomy jazyka C#neumožňují proměnné. Obvykle je to proto, že analýzu bezpečnosti ref nelze spolehlivě provést. - Výraz hodnoty použitý v případě potřeby referenční proměnné: Výraz použitý jako referenční proměnná musí být proměnnou, nikoli výraz hodnoty.
- Zapisovatelné referenční proměnné odkazující na proměnné jen pro čtení: Odkaz na proměnnou jen pro čtení nelze předat zapisovatelným odkazem.
- porušení bezpečnosti ref: Referenční proměnná nemůže odkazovat na proměnnou, která má užší kontext. To by znamenalo, že odkazová proměnná může odkazovat na neplatnou paměť.
Tento článek používá referenční proměnnou jako obecný termín pro parametr deklarovaný pomocí některého z in
, ref readonly
, ref
, , nebo out
modifikátorů, nebo ref
místní proměnné, ref
pole v ref struct
, nebo ref
návrat. Referenční proměnná odkazuje na jinou proměnnou, která se nazývá odkaz.
Nesprávná syntaxe
Tyto chyby značí, že používáte nesprávnou syntaxi týkající se referenčních proměnných:
- CS8373: Levá strana
ref
přiřazení musí být proměnnou odkazu. - CS8388: Proměnnou
out
nelze deklarovat jako místní odkaz. - CS9190:
readonly
Modifikátor musí být zadán zaref
.
Chybu můžete opravit jedním z těchto změn:
- Levý operand operátoru
= ref
musí být referenční proměnnou. Další informace o správné syntaxi najdete v referenčních proměnných. - Modifikátor
ref readonly
parametru musí být v daném pořadí.readonly ref
není modifikátor právního parametru. Přepněte pořadí slov. - Místní proměnnou nelze deklarovat jako
out
. Chcete-li deklarovat místní referenční proměnnou, použijteref
.
Omezení referenčních proměnných
Následující chyby značí, že referenční proměnnou nelze použít tam, kde ji máte:
- CS0631:
ref
aout
nejsou platné v tomto kontextu - CS0767: Nelze dědit rozhraní se zadanými parametry typu, protože způsobuje, že metoda obsahuje přetížení, které se liší pouze na
ref
aout
- CS1623: Iterátory nemohou mít
ref
parametryin
neboout
- CS1741: A
ref
neboout
parametr nemůže mít výchozí hodnotu - CS1939: Proměnnou
out
rozsahu nelze předat jako parametrref
- CS1988: Asynchronní metody nemohou mít
ref
parametryin
neboout
- CS7084: Událost prostředí Windows Runtime nemusí být předána
out
jako neboref
parametr. - CS8196: Odkaz na implicitně typovanou
out
proměnnou není povolen ve stejném seznamu argumentů. - CS8325: Příkaz await nelze použít ve výrazu obsahujícím podmíněný
ref
operátor. - CS8326: Obě hodnoty podmíněného operátoru musí být hodnoty ref nebo ani jedna z nich nesmí být hodnota ref.
- CS8327: Výraz musí být správný typ, aby odpovídal alternativní referenční hodnotě.
- CS8337: První parametr metody rozšíření '
ref
' musí být typ hodnoty nebo obecný typ omezený na strukturu. - CS8338: První parametr "
in
' nebo 'ref readonly
' metody rozšíření musí být konkrétní (ne generický) typ hodnoty. - CS8977: V podpisu metody s atributem UnmanagedCallersOnly nelze použít '
ref
', 'in
' nebo 'out
' - CS9072: Dekonstrukční proměnnou nelze deklarovat jako místní odkaz.
- CS9104: Prostředek
using
příkazu typu nelze použít v asynchronních metodách nebo asynchronních výrazech lambda. - CS9199: Parametr
ref readonly
nemůže mít atribut Out.
Následující upozornění značí, že referenční proměnná by se neměla používat a může být nebezpečná:
- CS9196: Modifikátor druh odkazu parametru neodpovídá odpovídajícímu parametru v přepsání nebo implementovaném členu.
- CS9197: Modifikátor druh odkazu parametru neodpovídá odpovídajícímu parametru ve skrytém členu.
- CS9198: Modifikátor druh odkazu parametru neodpovídá odpovídajícímu parametru v cíli.
- CS9200: Pro parametr je zadána
ref readonly
výchozí hodnota, aleref readonly
měla by být použita pouze pro odkazy. Zvažte deklarování parametru jakoin
. - CS9201: Pole Odkaz by mělo být před použitím přiřazeno odkazem.
- CS9265: Pole není nikdy přiřazeno odkazem a vždy bude mít výchozí hodnotu (odkaz null)
Pokud chcete chybu opravit, odeberte referenční proměnnou, kde není povolená:
- Odeberte
in
,ref
aout
parametry z indexerů, iterátorů a asynchronních metod. - Odeberte podmíněné výrazy ref (
? :
), které obsahují výraz await. ref
Odeberte modifikátor z prvního parametru metody rozšíření, kde tento typ není typ hodnoty nebo obecný typ omezený jako typ hodnoty.- Výrazy podmíněného operátoru nebo obě nesmí být
ref
proměnné. Buď odeberteref
jeden výraz, nebo ho přidejte do druhého. Pokud se jedná o podmíněnýref
výraz, musí být oba výrazy stejného typu. ref
aout
parametry nemohou mít výchozí hodnoty. Buď odeberteref
neboout
modifikátor, nebo odeberte výchozí hodnotu.- Deklarace implicitně zadané
out
proměnné se také nemůže objevit jinde ve stejném seznamu argumentů. - Referenční proměnné nelze vložit do
using
příkazu veasync
výrazech lambda metod. - Proměnná rozsahu ve výrazu dotazu LINQ nemůže být předána odkazem.
- Objekt nelze dekonstruovat do referenčních proměnných. Nahraďte referenční proměnné proměnnými hodnot.
- Nemůžete implementovat více rozhraní, kde se přetížení metody liší pouze na
ref
aout
. Například jedno rozhraní deklarujevoid M(ref int i)
a jiné rozhraní deklarujevoid M(out int i)
. Třída nemůže implementovat obě rozhraní, protože metody nejsou rozlišitelné. Můžete implementovat pouze jedno z těchto rozhraní. - Metody, které jsou přiřazeny, nemůžou System.Runtime.InteropServices.UnmanagedCallersOnlyAttribute používat referenční parametry.
- Událost modulu runtime systému Windows nelze předat jako referenční proměnnou.
- Parametr
ref readonly
na něj nemůže být System.Runtime.InteropServices.OutAttribute použit v rozhraní API vzdálené komunikace. - Inicializuje
ref
pole v konstruktoru nebo jako inicializátor pole.
unscoped ref
Omezení
Kvalifikátor unscoped
parametrů ref
není v některých umístěních povolený:
- CS9101: UnscopedRefAttribute lze použít pouze u struktur instance nebo virtuálních rozhraní metod a vlastností a nelze je použít u konstruktorů nebo inicializačních členů.
- CS9102: UnscopedRefAttribute nelze použít na implementaci rozhraní, protože implementovaný člen nemá tento atribut..
Je nutné odebrat unscoped
modifikátor deklarace parametru, která způsobila chybu.
Referenční proměnné vyžadují odkazující proměnnou.
Proměnnou musíte zadat jako argument referenčního parametru, návratu odkazu nebo místního přiřazení odkazu:
- CS0206: Nevrací vlastnost nebo indexer nelze použít jako
out
neboref
hodnotu. - CS1510: A
ref
neboout
hodnota musí být přiřaditelná proměnná.
Varování:
- CS9191:
ref
Modifikátor argumentu odpovídajícíin
parametru je ekvivalentníin
. Místo toho zvažte použitíin
. - CS9192: Argument by měl být předán s klíčovým slovem nebo
in
s klíčovým slovemref
. - CS9193: Argument by měl být proměnnou, protože je předán parametru
ref readonly
. - CS9195: Argument by měl být předán s klíčovým slovem
in
Kompilátor generuje tyto chyby při použití výrazu, který vypočítá hodnotu, ve které se musí použít proměnná. Výsledek tohoto výrazu musíte uložit do proměnné, aby ho bylo možné použít. Například vlastnosti a indexery vrací hodnoty, ne proměnné. Výsledek musíte uložit do proměnné a předat odkaz na tuto proměnnou.
Zapisovatelné referenční proměnné vyžadují zapisovatelný odkaz
Zapisovatelná referenční proměnná vyžaduje, aby odkaz byl zapisovatelný také. Následující chyby značí, že proměnná není zapisovatelná:
- CS0192: Pole
readonly
nelze použít jakoref
hodnotu neboout
hodnotu (s výjimkou konstruktoru). - CS0199: Pole
static readonly
nelze použít jakoref
neboout
hodnotu (s výjimkou statického konstruktoru). - CS1605: Proměnnou
ref
nelze použít jako hodnotu,out
protože je určena jen pro čtení - CS1649: Členy
readonly
pole nelze použít jakoref
hodnotu neboout
hodnotu (s výjimkou konstruktoru). - CS1651: Pole
static readonly
pole nelze použít jakoref
hodnotu neboout
hodnotu (s výjimkou statického konstruktoru). - CS1655: Nelze použít pole typu jako
ref
hodnotuout
- CS1657: Nelze použít proměnnou
ref
jako hodnotuout
- CS8329: Proměnnou
ref
nelze použít jako hodnotu,out
protože se jedná o proměnnou jen pro čtení - CS8330: Členy proměnné nelze použít jako
ref
hodnotu,out
protože se jedná o proměnnou jen pro čtení. - CS8331: Nelze přiřadit proměnnou nebo ji použít jako pravou stranu
ref
přiřazení, protože se jedná o proměnnou jen pro čtení - CS8332: Nelze přiřadit členu proměnné nebo jej použít jako pravou stranu
ref
přiřazení, protože se jedná o proměnnou jen pro čtení
Mezi příklady proměnných, které se nedají zapisovat, patří:
- pole jen pro čtení, instance i statická pole.
- Členové
readonly
polí. - Proměnná
this
. - Proměnná iterace foreach
- A using variable, or a fixed variable.
Je nutné zkopírovat hodnotu a předat odkaz na kopii.
Porušení bezpečnosti ref
Kompilátor sleduje bezpečný kontext odkazovaných a referenčních proměnných. Kompilátor vydává chyby nebo upozornění v nebezpečném kódu, pokud odkazová proměnná odkazuje na odkazující proměnnou, která už není platná. Odkazující musí mít bezpečný kontext, který je alespoň tak široký jako referenční bezpečný kontext referenční proměnné. Porušení těchto bezpečnostních kontrol znamená, že referenční proměnná přistupuje k náhodné paměti místo referenční proměnné.
- CS8166: Nelze vrátit parametr odkazem, protože se nejedná o
ref
parametr - CS8167: Nelze vrátit odkazem na člena parametru, protože se nejedná o
ref
parametrout
- CS8168: Nelze vrátit místní odkaz podle odkazu, protože se nejedná o odkaz na místní
- CS8169: Nelze vrátit člena místní proměnné odkazem, protože se nejedná o odkaz na místní
- CS8345: Pole nebo automaticky implementovaná vlastnost nemůže být typu, pokud není členem
ref struct
instance . - CS8351: Větve podmíněného operátoru
ref
nemohou odkazovat na proměnné s nekompatibilními obory deklarací - CS8374: Zdroj nelze ref-assign má užší řídicí obor než cíl.
- CS9077: Nelze vrátit parametr odkazem prostřednictvím parametru
ref
; může být vrácen pouze v návratovém příkazu. - CS9078: Nelze vrátit odkazem na člena parametru prostřednictvím parametru
ref
; může být vrácen pouze v návratovém příkazu. - CS9079: Nelze přiřadit zdroj k cíli, protože zdroj může utéct pouze aktuální metodu pomocí příkazu return.
- CS9096: Nelze přiřadit zdroj k cíli, protože zdroj má širší rozsah řídicí hodnoty než cíl umožňující přiřazení prostřednictvím cíle hodnot s užšími řídicími obory než zdroj.
Varování:
- CS9085: Tento odkaz přiřadí zdroj cíli, ale zdroj má užší řídicí obor než cíl.
- CS9086: Větve podmíněného operátoru odkazu odkazují na proměnné s nekompatibilními obory deklarací.
- CS9087: Vrátí parametr podle odkazu, ale nejedná se o
ref
parametr. - CS9089: Vrátí se odkazem na člena parametru, který není parametrem nebo
out
parametremref
. - CS9091: Vrátí místní hodnoty podle odkazu, ale nejedná se o odkaz na místní
- CS9092: Vrátí člena místního odkazu, ale nejedná se o odkaz na místní
- CS9093: Tento odkaz přiřadí zdroj k cíli, ale zdroj může utéct pouze aktuální metodu pomocí příkazu return.
- CS9094: Vrátí parametr odkazem prostřednictvím parametru
ref
, ale může být vrácen pouze v příkazu return. - CS9095: Tato funkce vrátí odkazem na člena parametru prostřednictvím parametru
ref
, ale může být vrácena pouze v příkazu return. - CS9097: Tento odkaz přiřadí zdroj cíli, ale zdroj má širší rozsah řídicích hodnot než cíl, který umožňuje přiřazení prostřednictvím cíle hodnot s užšími řídicími obory než zdroj.
Kompilátor pomocí statické analýzy určí, jestli je odkaz platný ve všech bodech, kde lze použít referenční proměnnou. Musíte refaktorovat kód tak, aby odkazující zůstal platný ve všech umístěních, kde na ni odkazující proměnná může odkazovat. Podrobnosti o pravidlech bezpečnosti ref najdete ve standardu C# týkajícím se bezpečných kontextů ref.