Megosztás a következőn keresztül:


Target-Typed feltételes kifejezés

Jegyzet

Ez a cikk egy funkcióspecifikáció. A specifikáció a funkció tervezési dokumentumaként szolgál. Tartalmazza a specifikáció javasolt módosításait, valamint a funkció tervezése és fejlesztése során szükséges információkat. Ezeket a cikkeket mindaddig közzéteszik, amíg a javasolt specifikációmódosításokat nem véglegesítik, és be nem építik a jelenlegi ECMA-specifikációba.

A szolgáltatás specifikációja és a befejezett implementáció között eltérések lehetnek. Ezeket a különbségeket a vonatkozó nyelvi tervezési értekezlet (LDM) megjegyzései rögzítik.

A funkcióspektusok C# nyelvi szabványba való bevezetésének folyamatáról a specifikációkcímű cikkben olvashat bővebben.

Bajnoki probléma: https://github.com/dotnet/csharplang/issues/2460

Feltételes kifejezés konvertálása

Feltételes kifejezés esetén c ? e1 : e2, amikor

  1. e1 és e2esetében nincs gyakori típus, vagy
  2. amelynél létezik egy közös típus, de az egyik kifejezés e1 vagy e2 nem rendelkezik implicit átalakítással erre a típusra

meghatározunk egy új implicit feltételes kifejezés konvertálási, amely lehetővé teszi a feltételes kifejezés implicit konvertálását bármely olyan T típusra, amelyhez e1-ról T- és e2T. Hiba, ha egy feltételes kifejezés sem rendelkezik közös típussal e1 és e2 között, sem pedig nem vonatkozik a feltételes kifejezés konvertálására.

Jobb konverzió kifejezésből

Módosítjuk

Jobb átalakítás a kifejezésből

Egy implicit konverzió C1, amely egy kifejezésből E típussá T1konvertál, és egy implicit konverzió C2, amely egy kifejezésből E típussá T2konvertál, esetében C1 egy jobb konverzió, mint C2, ha E nem egyezik meg pontosan T2, és az alábbi feltételek közül legalább egy teljesül:

hoz

Jobb átalakítás a kifejezésből

Egy implicit konverzió C1, amely egy kifejezésből E típussá T1konvertál, és egy implicit konverzió C2, amely egy kifejezésből E típussá T2konvertál, esetében C1 egy jobb konverzió, mint C2, ha E nem egyezik meg pontosan T2, és az alábbi feltételek közül legalább egy teljesül:

  • E pontosan egyezik T1 (§12.6.4.5)
  • C1 nem feltételes kifejezés konverzió, és C2feltételes kifejezés konverzió.
  • T1 jobb konverziós cél, mint T2 (§12.6.4.7) és vagy C1 és C2 mindkettő feltételes kifejezési konverzió, vagy egyik sem feltételes kifejezési konverzió.

Öntött kifejezés

A jelenlegi C# nyelvspecifikáció szerint

Az űrlap (T)E , ahol Ttípusú és Eunary_expression, a értékének explicit konvertálását hajtja végre (E) Ttípusra .

A feltételes kifejezés jelenlétében többféle átalakítás is lehetséges E-ről T-ra. A feltételes kifejezések átalakításánakhozzáadásával előnyben részesítünk minden más átalakítást a feltételes kifejezés konvertálásávalszemben, és a feltételes kifejezés konvertálását csak végső megoldásként használjuk.

Tervezési megjegyzések

A változás oka kifejezésről jobb konvertálásra egy ilyen eset kezelése:

M(b ? 1 : 2);

void M(short);
void M(long);

Ennek a megközelítésnek két kis hátránya van. Először is, ez nem teljesen ugyanaz, mint a kapcsolókifejezés:

M(b ? 1 : 2); // calls M(long)
M(b switch { true => 1, false => 2 }); // calls M(short)

Ez továbbra is kompatibilitástörő változás, de hatóköre kisebb valószínűséggel lesz hatással a valódi programokra:

M(b ? 1 : 2, 1); // calls M(long, long) without this feature; ambiguous with this feature.

M(short, short);
M(long, long);

Ez azért nem egyértelmű, mert az long konvertálása jobb az első argumentumhoz (mivel nem használja a feltételes kifejezés konvertálását), de a short konvertálása a második argumentum esetében jobb (mivel shortjobb konverziós cél, mint long). Ez a kompatibilitástörő változás kevésbé súlyosnak tűnik, mert nem változtatja meg csendben egy meglévő program viselkedését.

A leadott kifejezés megjegyzéseinek oka egy ilyen eset kezelése:

_ = (short)(b ? 1 : 2);

Ez a program jelenleg a int explicit konvertálását használja short, és meg szeretnénk őrizni a program aktuális nyelvi jelentését. A változás futásidőben elérhetetlen lenne, de a következő programnál a változás megfigyelhető lenne:

_ = (A)(b ? c : d);

ahol a c a Ctípusú, a d a Dtípusú, és van egy implicit, felhasználó által definiált átalakítás a C-ről D-re, a D-ról A-re, valamint a C-ról A-re. Ha ez a kód a C# 9.0 előtt van lefordítva, b igaz, c-ről D-ra konvertáljuk, majd A. Ha a feltételes kifejezés konvertálásáthasználjuk, akkor ha b igaz, közvetlenül cA alakítunk át, amely egy másik felhasználói kódsorozatot hajt végre. Ezért a feltételes kifejezés átalakítását végső megoldásként kezeljük egy típuskonverzió során, hogy megőrizzük a meglévő viselkedést.