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


Céltípusú new kifejezések

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/100

Összefoglalás

Ha a típus ismert, ne követelje meg a konstruktorok típusspecifikációját.

Motiváció

A mező inicializálásának engedélyezése a típus duplikálása nélkül.

Dictionary<string, List<int>> field = new() {
    { "item1", new() { 1, 2, 3 } }
};

Engedélyezze a típus kihagyását, ha a használatból következtetni lehet rá.

XmlReader.Create(reader, new() { IgnoreWhitespace = true });

Példányosítson egy objektumot a típus pontos megnevezése nélkül.

private readonly static object s_syncObj = new();

Előírás

Az új szintaktikai formát, a target_typed_new a object_creation_expression esetében, elfogadják, amelyben a típus nem kötelező.

object_creation_expression
    : 'new' type '(' argument_list? ')' object_or_collection_initializer?
    | 'new' type object_or_collection_initializer
    | target_typed_new
    ;
target_typed_new
    : 'new' '(' argument_list? ')' object_or_collection_initializer?
    ;

A target_typed_new kifejezések nem rendelkeznek típussal. Van azonban egy új objektumlétrehozás-átalakítás, amely egy kifejezés alapú implicit átalakítás, és amely egy target_typed_new-ból minden típusra érvényes.

Adott céltípus Tesetén a T0 típus a Tmögöttes típusa, ha T a System.Nullablepéldánya. Ellenkező esetben T0T. A típussá konvertált T kifejezés jelentése megegyezik egy megfelelő object_creation_expression jelentésével, amely T0 a típusként határozza meg.

Fordítási idejű hiba, ha egy target_typed_new egy unáris vagy bináris operátor operandusaként használják, vagy ha olyan esetben használják, ahol nem vonatkozik rá objektumlétrehozási konverzió.

Nyitott probléma: engedélyezni kell a meghatalmazottak és a tupulusok céltípusként való használatát?

A fenti szabályok közé tartoznak a delegátumok (referenciatípus) és a tuplek (struktúratípus). Bár mindkét típus konstruálható, ha a típus levonható, egy névtelen függvény vagy egy rekordkonstans már használható.

(int a, int b) t = new(1, 2); // "new" is redundant
Action a = new(() => {}); // "new" is redundant

(int a, int b) t = new(); // OK; same as (0, 0)
Action a = new(); // no constructor found

Vegyes

A specifikáció következményei a következők:

  • throw new() engedélyezett (a céltípus System.Exception)
  • A cél típusú new bináris operátorok esetén nem engedélyezett.
  • Nem engedélyezett, ha nincs céltípus: egyváltozós operátorok, foreachgyűjteménye, using, dekonstruálásban, await kifejezésben, névtelen típusú tulajdonságként (new { Prop = new() }), lock utasításban, sizeof, fixed utasításban, taghozzáférésben (new().field), dinamikusan küldött műveletben (someDynamic.Method(new())), LINQ-lekérdezésben, mint a is operátor operandusa, mint a ?? operátor bal operandusa, ...
  • ref-ként is tiltott.
  • A következő típustípusok nem engedélyezettek az átalakítás céljaként
    • Enum típusok:new() működni fog (mivel new Enum() az alapértelmezett értéket adja meg), de new(1) nem fog működni, mivel a számtípusok nem rendelkeznek konstruktorsal.
    • felülettípusok: Ez ugyanúgy működik, mint a COM-típusok megfelelő létrehozási kifejezése.
    • tömbtípusok: tömböknek speciális szintaxisra van szükségük a hossz megadásához.
    • dinamikus: nem engedélyezzük a new dynamic(), ezért nem engedélyezzük new()dynamic céltípusként.
    • tuplák: Ezeknek a jelentése megegyezik az alapul szolgáló típust használó objektum létrehozásának jelentésével.
    • A object_creation_expression nem engedélyezett összes többi típust is kizárjuk, például a mutatótípusokat.

Hátránya

Voltak aggodalmak a cél típusú new új megszakító változások kategóriáinak létrehozásával kapcsolatban, de már rendelkezünk ezzel null és defaultesetében is, és ez nem volt jelentős gond.

Alternatívák

A legtöbb olyan panasz, amely szerint a típusok túl hosszúak a mező inicializálásában való duplikáláshoz, típusargumentumokról van szó, nem magát a típust, csak olyan típusargumentumokat tudunk kikövetkeztetni, mint a new Dictionary(...) (vagy hasonló) és a típusargumentumokat helyileg az argumentumokból vagy a gyűjtemény inicializálójából.

Kérdések

  • Tiltsuk be a kifejezési fák használatát? (nem)
  • Hogyan működik a funkció dynamic argumentumokkal? (nincs különleges kezelés)
  • Hogyan kellene működnie az IntelliSense-nek a new()esetében? (csak akkor, ha egyetlen céltípus létezik)

Design értekezletek