Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
parametry
Poznámka
Tento článek je specifikace funkce. Specifikace slouží jako návrhový dokument pro funkci. Zahrnuje navrhované změny specifikace spolu s informacemi potřebnými při návrhu a vývoji funkce. Tyto články se publikují, dokud nebudou navrhované změny specifikace finalizovány a začleněny do aktuální specifikace ECMA.
Mezi specifikací funkce a dokončenou implementací může docházet k nějakým nesrovnalostem. Tyto rozdíly jsou zachyceny v příslušných poznámkách ze schůzky návrhu jazyka (LDM) .
Další informace o procesu přijetí specifikací funkcí do jazyka C# najdete v článku o specifikacích .
Problém šampiona: https://github.com/dotnet/csharplang/issues/6010
Shrnutí
Povolte modifikátor místa deklarace parametrů ref readonly a změňte pravidla volání takto:
| Poznámky k volání | parametr ref |
parametr ref readonly |
parametr in |
parametr out |
|---|---|---|---|---|
ref |
Povoleno | povolené | upozornění | Chyba |
in |
Chyba | povolené | Povoleno | Chyba |
out |
Chyba | Chyba | Chyba | Povoleno |
| Žádná poznámka | Chyba | upozornění | Povoleno | Chyba |
(Všimněte si, že existuje jedna změna stávajících pravidel: parametr in s anotací místa volání ref generuje upozornění místo chyby.)
Změňte pravidla hodnot argumentu následujícím způsobem:
| Druh hodnoty | parametr ref |
parametr ref readonly |
parametr in |
parametr out |
|---|---|---|---|---|
| rvalue | Chyba | upozornění | Povoleno | Chyba |
| lvalue | Povoleno | povolené | Povoleno | Povoleno |
Pokud hodnota lvalue znamená proměnnou (tj. hodnotu s umístěním; nemusí být zapisovatelná/přiřaditelná) a hodnota rvalue znamená jakýkoli druh hodnoty.
Motivace
C# 7.2 zavedl in parametry jako způsob předávání odkazů jen pro čtení.
in parametr umožňuje hodnoty lvalue i rvalue a lze jej použít bez jakékoli poznámky při volání.
Rozhraní API, která zaznamenávají nebo vracejí odkazy ze svých parametrů, by však ráda zakázala hodnoty rvalue a také prosadila nějaké označení na místě volání, že je zachycen odkaz.
ref readonly parametry jsou ideální v takových případech, protože varují, pokud se používají s r-hodnotami nebo bez jakékoli poznámky v místě volání.
Kromě toho existují rozhraní API, která potřebují pouze odkazy pro čtení, ale používají tyto odkazy.
-
refparametry, protože byly zavedeny dříve, než bylyindostupné a změna nainby znamenala zásadní změnu zdrojového i binárního kódu, napříkladQueryInterfacenebo - cs-CZ:
inparametry pro přijímání referenčních odkazů pouze pro čtení, i když předávání r-hodnot do nich ve skutečnosti není logické, napříkladReadOnlySpan<T>..ctor(in T value), nebo -
refparametry k zakázání rvalues, i když nemodifikují předanou referenci, napříkladUnsafe.IsNullRef.
Tato rozhraní API by mohla migrovat na parametry ref readonly, aniž by přerušila fungování pro uživatele.
Podrobnosti o binární kompatibilitě najdete v navrhovaném kódování metadat .
Konkrétně změna
-
ref→ref readonlyby znamenala pouze binární nekompatibilitu pro virtuální metody. -
ref→inby také byla binární zlomová změna virtuálních metod, ale ne zdrojová zlomová změna, protože pravidla se změní, aby varovala pouze narefargumenty předané parametrůmin. -
in→ref readonlyby nebyla změna narušující kompatibilitu (ale žádné poznámky na místě volání ani rvalue by nevedly k upozornění).- Všimněte si, že by to byla změna vedoucí k chybě kompatibility pro uživatele používající starší verze kompilátoru (protože interpretují parametry
ref readonlyjako parametryref, což neumožňuje použitíinnebo žádné anotace na volajícím místě) a pro nové verze kompilátoru sLangVersion <= 11(pro zachování konzistence se staršími verzemi kompilátoru bude vydána chyba, že parametryref readonlynejsou podporovány, pokud nebudou předány odpovídající argumenty s modifikátoremref).
- Všimněte si, že by to byla změna vedoucí k chybě kompatibility pro uživatele používající starší verze kompilátoru (protože interpretují parametry
V opačném směru se mění
-
ref readonly→refby mohlo dojít ke změně narušující zdrojový kód (pokud byla použita pouze anotace volánírefa jako argumenty byly používány jen odkazy vyhrazené pro čtení) a binární změna narušující kompatibilitu pro virtuální metody, -
ref readonly→inby nebyla zásadní změna (ale anotace místa volánírefby vedla k upozornění).
Všimněte si, že výše uvedená pravidla platí pro podpisy metod, ale ne pro podpisy delegátů.
Změna ref na in v podpisu delegáta může být například změna způsobující chybu zdroje (pokud uživatel přiřazuje metodu s parametrem ref danému typu delegáta, stane se po změně rozhraní API chybou).
Podrobný návrh
Obecně platí, že pravidla pro parametry ref readonly jsou stejná jako pro parametry in v jejich návrhus výjimkou případů, kdy se explicitně změnily v tomto návrhu.
Deklarace parametrů
Nejsou potřeba žádné změny gramatiky.
Modifikátor ref readonly bude pro parametry povolen.
Kromě normálních metod budou ref readonly povoleny pro parametry indexeru (například in, ale na rozdíl od ref), ale nepovolené pro parametry operátoru (například ref, ale na rozdíl od in).
Výchozí hodnoty parametrů budou povoleny pro parametry ref readonly s upozorněním, protože jsou ekvivalentní předávání hodnot rvalue.
To umožňuje autorům rozhraní API změnit parametry in s výchozími hodnotami na ref readonly parametry bez zavedení změny způsobující chybu zdroje.
Kontroly typu hodnoty
Všimněte si, že i když je modifikátor argumentu ref povolený pro parametry ref readonly, nic se nezmění, pokud jde o kontroly typu hodnoty, tj.
-
reflze použít pouze s přiřaditelnými hodnotami; - pro předávání odkazů jen pro čtení, jeden musí místo toho použít modifikátor argumentu
in; - pro předávání hodnot rvalue nemusíte použít žádný modifikátor (což vede k upozornění na parametry
ref readonly, jak je popsáno v souhrnu tohoto návrhu).
Rozlišení přetížení
Rozlišení přetížení umožní kombinovat ref/ref readonly/inbez volání poznámek a modifikátory parametrů, které jsou označeny tabulkou v souhrnu tohoto návrhu, tj. všechny povolené a varování případy budou během řešení přetížení považovány za možné kandidáty.
Konkrétně se jedná o změnu stávajícího chování, kdy metody s parametrem in budou odpovídat voláním s odpovídajícím argumentem označeným jako ref— tato změna bude řízena verzí jazyka.
Upozornění pro předání argumentu bez modifikátoru volání do parametru ref readonly se však potlačí, pokud parametr je
- příjemce při vyvolání metody rozšíření,
- používá se implicitně jako součást inicializátoru vlastní kolekce nebo zpracování interpolovaných řetězců.
Přetížení podle hodnoty budou upřednostňována před přetížením ref readonly v případě, že není přítomen žádný modifikátor argumentu (in parametry mají stejné chování).
Převody metod
Podobně pro účely anonymní funkce [§10.7] a skupiny metod [§10.8] převody jsou tyto modifikátory považovány za kompatibilní (ale jakákoli povolená konverze mezi různými modifikátory vede k upozornění):
-
ref readonlyparametr cílové metody může odpovídat parametruinneborefdelegáta, -
inparametr cílové metody může odpovídatref readonlynebo, pokud to dovoluje verze jazyka,refparametru delegáta. - Poznámka:
refparametr cílové metody není povoleno shodovatinaniref readonlyparametr delegáta.
Například:
DIn dIn = (ref int p) => { }; // error: cannot match `ref` to `in`
DRef dRef = (in int p) => { }; // warning: mismatch between `in` and `ref`
DRR dRR = (ref int p) => { }; // error: cannot match `ref` to `ref readonly`
dRR = (in int p) => { }; // warning: mismatch between `in` and `ref readonly`
dIn = (ref readonly int p) => { }; // warning: mismatch between `ref readonly` and `in`
dRef = (ref readonly int p) => { }; // warning: mismatch between `ref readonly` and `ref`
delegate void DIn(in int p);
delegate void DRef(ref int p);
delegate void DRR(ref readonly int p);
Všimněte si, že nedošlo ke změně v chování při převodech ukazatelů funkce . Připomeňme si, že implicitní konverze ukazatelů na funkce jsou zakázány, pokud dojde k neshodě mezi modifikátory typu reference, a explicitní přetypy jsou vždy povoleny bez upozornění.
Porovnávání podpisů
Členy deklarované v jednom typu se nemohou lišit pouze v podpisu ref/out/in/ref readonly.
Pro jiné účely porovnávání podpisů (např. skrytí nebo přepsání) lze ref readonly zaměnit s modifikátorem in, ale výsledkem je upozornění na místě deklarace [§7.6].
To neplatí při porovnávání deklarace partial s implementací a při porovnávání signatury zachytávače s zachycenou signaturou.
Všimněte si, že nedochází ke změnám v přepisu pro páry modifikátorů ref/in a ref readonly/ref; nelze je zaměnit, protože podpisy nejsou binárně kompatibilní.
Pro konzistenci platí totéž pro jiné účely porovnávání podpisů (např. skrytí).
Kódování metadat
Jako připomenutí
-
refparametry jsou emitovány jako prosté typy byref (T&v IL), -
inparametry jsou jakorefa navíc jsou opatřeny poznámkamiSystem.Runtime.CompilerServices.IsReadOnlyAttribute. V C# 7.3 a novějších verzích jsou také vytvářeny s[in]a pokud jsou virtuální, smodreq(System.Runtime.InteropServices.InAttribute).
ref readonly parametry budou vydány jako [in] T&a budou dále opatřeny následujícím atributem:
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
public sealed class RequiresLocationAttribute : Attribute
{
}
}
Navíc, pokud jsou virtuální, budou emitovány s modreq(System.Runtime.InteropServices.InAttribute), aby se zajistila binární kompatibilita s parametry in.
Všimněte si, že na rozdíl od parametrů in se pro [IsReadOnly] parametry nevygenerují žádné ref readonly, aby nedocházelo ke zvýšení velikosti metadat a také aby starší verze kompilátoru interpretovala parametry ref readonly jako parametry ref (a proto ref → ref readonly nebude zásadní změnou zdroje ani mezi různými verzemi kompilátoru).
RequiresLocationAttribute se bude shodovat s názvem kvalifikovaným oborem názvů a syntetizován kompilátorem, pokud ještě není součástí kompilace.
Zadání atributu ve zdroji bude chybou, pokud se použije u parametru, podobně jako u ParamArrayAttribute.
Ukazatele na funkce
Ve funkčních ukazatelích se parametry in vysílají pomocí modreq(System.Runtime.InteropServices.InAttribute) (viz návrh funkčních ukazatelů).
Parametry ref readonly budou vydávány bez této modreq, ale s modopt(System.Runtime.CompilerServices.RequiresLocationAttribute).
Starší verze kompilátoru budou ignorovat modopt, a proto interpretuji parametry ref readonly jako parametry ref (v souladu se starším chováním kompilátoru pro normální metody s parametry ref readonly, jak je popsáno výše). Nové verze kompilátoru, které jsou si vědomy modopt, budou využívat tuto informaci k rozeznávání ref readonly parametrů, což povede ke generování upozornění během konverzí a vyvolání .
Pro zachování konzistence se staršími verzemi kompilátoru budou nové verze kompilátoru s LangVersion <= 11 hlásit chyby, že parametry ref readonly nejsou podporovány, pokud nejsou předány odpovídající argumenty s modifikátorem ref.
Všimněte si, že změna modifikátorů v signaturách ukazatelů na funkce, pokud jsou součástí veřejných API, představuje binární zlom, a proto se jedná o binární zlom při změně ref nebo in na ref readonly.
K přerušení zdroje dojde pouze u volajících s LangVersion <= 11 při změně in → ref readonly (pokud vyvoláte ukazatel s modifikátorem in volání), což je v souladu s běžnými metodami.
Zásadní změny
Redukce nesouladu ref/in v řešení přetížení představuje změnu narušující chování, jak ukazuje následující příklad:
class C
{
string M(in int i) => "C";
static void Main()
{
int i = 5;
System.Console.Write(new C().M(ref i));
}
}
static class E
{
public static string M(this C c, ref int i) => "E";
}
V jazyce C# 11 se volání sváže s E.M, a proto se vytiskne "E".
V jazyce C# 12 je C.M umožněno svázat (s upozorněním) a nejsou prohledány žádné obory rozšíření, protože máme vhodného kandidáta, a proto se vytiskne "C".
Existuje také změna způsobující chybu zdroje z důvodu stejného důvodu.
Následující příklad zobrazí "1" v jazyce C# 11, ale nelze zkompilovat kvůli chybě nejednoznačnosti v jazyce C# 12.
var i = 5;
System.Console.Write(C.M(null, ref i));
interface I1 { }
interface I2 { }
static class C
{
public static string M(I1 o, ref int x) => "1";
public static string M(I2 o, in int x) => "2";
}
Výše uvedené příklady ukazují přerušení při volání metod, ale vzhledem k tomu, že jsou způsobeny změnami v rozlišení přetíženého vyhodnocování, mohou být podobně vyvolány pro převody metod.
Alternativy
deklarace parametrů
Autoři rozhraní API mohou označit parametry in, které jsou určeny pouze k přijímání lvalue, pomocí vlastního atributu a poskytnout analyzátor, jenž označuje nesprávné použití.
To by autorům rozhraní API neumožňovalo měnit podpisy existujících rozhraní API, která se přihlásila k použití parametrů ref k zakázání hodnot rvalue.
Volající takových rozhraní API by stále museli provádět další práci, aby získali ref, pokud mají přístup pouze k proměnné ref readonly.
Změna těchto rozhraní API z ref na [RequiresLocation] in by přinesla nekompatibilitu se zdrojovým kódem (a v případě virtuálních metod také binární nekompatibilitu).
Místo povolení modifikátoru ref readonlymůže kompilátor rozpoznat, kdy se na parametr použije speciální atribut (například [RequiresLocation]).
Bylo diskutováno v LDM 2022-04-25, rozhodnuto, že se jedná o jazykovou funkci, ne analyzátor, takže by měla vypadat jako taková.
kontroly typů hodnot
Předávání hodnot lvalue bez jakýchkoli modifikátorů do ref readonly parametrů může být povoleno bez jakýchkoli upozornění, podobně jako implicitní parametry C++.
To bylo diskutováno v LDM 2022-05-11, přičemž bylo poznamenáno, že primární motivací pro parametry ref readonly jsou rozhraní API, která zachycují nebo vracejí odkazy z těchto parametrů, takže nějaký druh indikátoru je dobrá věc.
Předání rvalue do ref readonly může být spíše chybou než upozorněním.
To bylo původně přijato v LDM 2022-04-25, ale pozdější e-mailové diskuze zmírnily tuto pozici, protože bychom ztratili možnost měnit stávající API bez narušení uživatelského prostředí.
in může být "přirozeným" modifikátorem volání pro parametry ref readonly a použití ref může vést k upozorněním.
Tím zajistíte konzistentní styl kódu a zviditelníte, že odkaz je jen pro čtení (na rozdíl od ref).
Původně byl přijat v LDM 2022-04-25.
Upozornění ale můžou být sporné body pro autory rozhraní API, aby přešli z ref na ref readonly.
Také in byl předefinován jako ref readonly + praktické funkce, a proto byl v LDM 2022-05-11odmítnut.
Čeká na přezkoumání LDM
V jazyce C# 12 nebyla implementována žádná z následujících možností. Návrhy zůstávají potenciální.
deklarace parametrů
Je možné povolit inverzní řazení modifikátorů (readonly ref místo ref readonly).
To by bylo nekonzistentní s tím, jak se readonly ref vrací a jak se pole chovají (inverzní řazení je zakázáno nebo znamená něco jiného) a mohlo by kolidovat s parametry určenými pouze ke čtení, pokud by byly v budoucnu implementovány.
Výchozí hodnoty parametrů mohou být chybou pro parametry ref readonly.
kontroly typů hodnot
Chyby mohou být generovány místo upozornění při předávání rhodnot do ref readonly parametrů nebo při neshodě poznámek na místě volání a modifikátorů parametrů.
Podobně lze místo atributu použít speciální modreq, aby se zajistilo, že parametry ref readonly se liší od parametrů in na binární úrovni.
To by poskytovalo silnější záruky, takže by bylo vhodné pro nová rozhraní API, ale zabránit přijetí ve stávajících rozhraních API modulu runtime, která nemohou zavádět zásadní změny.
Kontroly druhu hodnoty mohou být zmírněny, aby bylo možné předávat reference pouze pro čtení prostřednictvím ref do parametrů in/ref readonly.
To by bylo podobné tomu, jak dnes fungují přiřazení a vracení odkazů – také umožňují předávání odkazů jako pouze pro čtení prostřednictvím modifikátoru ref ve zdrojovém výrazu.
Nicméně, ref je obvykle blízko místa, kde cíl je deklarován jako ref readonly, takže je jasné, že předáváme odkaz jako jen pro čtení, na rozdíl od vyvolání, jejichž argument a modifikátory parametrů jsou obvykle daleko od sebe.
Kromě toho umožňují pouze modifikátoru ref na rozdíl od argumentů, které umožňují také in, a proto in a ref budou zaměnitelné pro argumenty nebo in budou prakticky zastaralé, pokud by uživatelé chtěli svůj kód konzistentně použít (pravděpodobně by používali ref všude, protože je to jediný modifikátor povolený pro přiřazení ref a vrácení odkazu).
rozlišení přetížení
Rozlišení přetížení, přepsání a převod by mohly zakázat záměnnost modifikátorů ref readonly a in.
Změna rozlišení přetížení pro existující in parametry by mohla být provedena bezpodmínečně (bez ohledu na LangVersion), ale to by byla zásadní změna.
Vyvolání metody rozšíření s příjemcem ref readonly může vést k upozornění „Argument 1 by se měl předat s klíčovým slovem ref nebo in“, podobně jako by tomu bylo u vyvolání bez rozšíření bez modifikátorů volajících. Uživatel může toto upozornění opravit tím, že změní vyvolání metody rozšíření na vyvolání statické metody.
Stejné upozornění může být hlášeno při použití vlastní inicializátoru kolekce nebo interpolované obslužné rutiny řetězců s parametrem ref readonly, i když uživatel ho nemohl obejít.
ref readonly přetížení lze upřednostňovat před přetíženími podle hodnoty, pokud neexistuje žádný modifikátor volání nebo může dojít k nejednoznačnosti chyby.
Převody metod
Mohli bychom povolit, aby parametr ref cílové metody odpovídal in a ref readonly parametr delegáta.
To by autorům rozhraní API umožnilo změnit například ref na in v podpisech delegátů bez narušení uživatelů (konzistentně s povolenými podpisy normální metody).
Výsledkem by však bylo také následující porušení readonly záruk s pouhým upozorněním:
class Program
{
static readonly int f = 123;
static void Main()
{
var d = (in int x) => { };
d = (ref int x) => { x = 42; }; // warning: mismatch between `ref` and `in`
d(f); // changes value of `f` even though it is `readonly`!
System.Console.WriteLine(f); // prints 42
}
}
Převody ukazatelů funkce by mohly upozornit na neshodu ref readonly/ref/in, ale pokud bychom chtěli, aby to bylo vázáno na verzi jazyka LangVersion, vyžadovala by se značná investice do implementace, protože převody typů dnes nevyžadují přístup k procesu kompilace.
I když je neshoda v současné době chybou, uživatelům je navíc snadné přidat přetypování, aby v případě potřeby povolili neshodu.
kódování metadat
Zadání RequiresLocationAttribute ve zdroji může být povoleno podobně jako atributy In a Out.
Alternativně to může být chyba při použití v jiných kontextech než jen parametry, podobně jako atribut IsReadOnly; aby se zachoval další prostor pro návrh.
Ukazatel funkce ref readonly parametry mohou být generovány různými kombinacemi modopt/modreq (všimněte si, že "konec zdroje" v této tabulce znamená pro volající s LangVersion <= 11):
| Modifikátory | Lze rozpoznat napříč kompilacemi. | Staré kompilátory je vidí jako |
ref → ref readonly |
in → ref readonly |
|---|---|---|---|---|
modreq(In) modopt(RequiresLocation) |
Ano | in |
binární soubor, konec zdroje | binární přerušení |
modreq(In) |
Ne | in |
binární soubor, konec zdroje | Ok |
modreq(RequiresLocation) |
Ano | nepodporovaný | binární soubor, konec zdroje | binární soubor, konec zdroje |
modopt(RequiresLocation) |
Ano | ref |
binární přerušení | binární soubor, konec zdroje |
Pro parametry [RequiresLocation] bychom mohli vygenerovat atributy [IsReadOnly] i ref readonly.
Pak in → ref readonly by nebyla zásadní změnou ani pro starší verze kompilátoru, ale ref → ref readonly by se stala zásadní změnou zdroje pro starší verze kompilátoru (protože by interpretovaly ref readonly jako in, nepovolovaly ref modifikátory) a nové verze kompilátoru s LangVersion <= 11 (pro konzistenci).
Chování pro LangVersion <= 11 se může lišit od chování starších verzí kompilátoru.
Například by to mohla být chyba při každém volání parametru ref readonly (i při použití modifikátoru ref na místě volání), nebo by to mohlo být vždy povoleno bez chyb.
Zásadní změny
Tento návrh doporučuje přijetí změny, která porušuje chování, protože by měla být vzácná, je řízena verzí jazyka LangVersion a uživatelé ji mohou obejít explicitním voláním metody rozšíření. Místo toho bychom ho mohli zmírnit
- zakázání neshody
ref/in(to by zabránilo migraci pouze nainpro stará rozhraní API, která používalaref, protožeinještě nebyla dostupná) - úprava pravidel řešení přetížení tak, aby nadále hledala lepší shodu (určená níže uvedenými pravidly zlepšení), pokud v tomto návrhu došlo k neshodě typu ref,
- nebo případně pokračujte pouze pro neshodu
refvs.in, ne u ostatních (ref readonlyvs.ref/in/by-value).
- nebo případně pokračujte pouze pro neshodu
Pravidla k lepšímu
Následující příklad aktuálně vede k třem nejednoznačným chybám pro tři vyvolání M.
Mohli bychom přidat nová pravidla lepšího řešení nejednoznačností.
Tím by se vyřešila také výše popsaná změna způsobující chybu zdroje.
Jedním ze způsobů by bylo nastavení příkladu, aby vytiskl 221 (kde se parametr ref readonly shoduje s argumentem in, protože volání bez modifikátoru by vyvolalo varování, zatímco pro parametr in je toto volání povoleno).
interface I1 { }
interface I2 { }
class C
{
static string M(I1 o, in int i) => "1";
static string M(I2 o, ref readonly int i) => "2";
static void Main()
{
int i = 5;
System.Console.Write(M(null, ref i));
System.Console.Write(M(null, in i));
System.Console.Write(M(null, i));
}
}
Nová pravidla zlepšení mohou označit parametr jako horší, kdy by jeho argument mohl být předán s jiným modifikátorem, aby byl lepší.
Jinými slovy, uživatel by měl být vždy schopen změnit horší parametr na lepší parametr změnou jeho odpovídajícího modifikátoru argumentu.
Pokud je například argument předán in, je preferován parametr ref readonly před parametrem in, protože uživatel může předat argument formou hodnoty a zvolit parametr in.
Toto pravidlo je pouze rozšířením pravidla předvoleb podle hodnoty neboin, které je v platnosti dnes (jedná se o poslední pravidlo řešení přetížení a celé přetížení je lepší, pokud je některý z jeho parametrů lepší a žádný není horší než odpovídající parametr jiného přetížení).
| argument | lepší parametr | horší parametr |
|---|---|---|
ref/in |
ref readonly |
in |
ref |
ref |
ref readonly/in |
| podle hodnoty | podle hodnoty/in |
ref readonly |
in |
in |
ref |
Podobně bychom měli zpracovávat převody metod.
Následující příklad momentálně vede ke dvěma nejednoznačnostním chybám při přiřazení dvou delegátů.
Nová pravidla zlepšení by mohla upřednostňovat parametr metody, jehož modifikátor "refness" odpovídá modifikátoru "refness" v odpovídajícím parametru cílového delegáta před těmi, které mají nesoulad.
Proto by následující příklad vytiskl 12.
class C
{
void M(I1 o, ref readonly int x) => System.Console.Write("1");
void M(I2 o, ref int x) => System.Console.Write("2");
void Run()
{
D1 m1 = this.M;
D2 m2 = this.M; // currently ambiguous
var i = 5;
m1(null, in i);
m2(null, ref i);
}
static void Main() => new C().Run();
}
interface I1 { }
interface I2 { }
class X : I1, I2 { }
delegate void D1(X s, ref readonly int x);
delegate void D2(X s, ref int x);
Kreativní schůzky
- LDM 2022-04-25: akceptovaná funkce
- LDM 2022-05-09: diskuze rozdělená do tří částí
-
LDM 2022-05-11: povoleno
refa nejsou popisky volaného místa pro parametryref readonly
C# feature specifications