Výrazy new
typu cíle
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. Poznámky ze schůzky o návrhu jazyka (LDM) zachycují tyto rozdíly.
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/100
Shrnutí
Pokud je typ známý, nevyžadují specifikaci typu pro konstruktory.
Motivace
Povolit inicializaci polí bez duplikování typu
Dictionary<string, List<int>> field = new() {
{ "item1", new() { 1, 2, 3 } }
};
Povolte vynechání typu, když ho lze odvodit z použití.
XmlReader.Create(reader, new() { IgnoreWhitespace = true });
Bez výslovného uvedení typu vytvořte instanci objektu.
private readonly static object s_syncObj = new();
Specifikace
Nová syntaktická forma, target_typed_newobject_creation_expression, ve které je typ volitelný, je přijata.
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?
;
Výraz target_typed_new neobsahuje typ. Existuje však nový převod objektu, který je implicitním převodem vycházejícím z výrazu target_typed_new na každý jeden typ.
Je-li dán cílový typ T
, pak je základním typem T
typ T0
, pokud je T
instancí System.Nullable
. V opačném případě T0
je T
. Význam výrazu target_typed_new převedeného na typ T
je stejný jako význam odpovídajícího object_creation_expression, který určuje T0
jako typ.
Jedná se o chybu v době kompilace, pokud se target_typed_new používá jako operand unárního nebo binárního operátoru, nebo pokud se používá tam, kde není předmětem převodu objektu.
Otevřený problém: měli bychom povolit delegáty a n-tice jako cílový typ?
Výše uvedená pravidla zahrnují delegáty (referenční typ) a n-tice (strukturovaný typ). I když jsou oba typy konstruktovatelné, pokud je typ odvozený, je možné použít anonymní funkci nebo literál řazené kolekce členů.
(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
Různé
Toto jsou důsledky specifikace:
-
throw new()
je povolená (cílový typ jeSystem.Exception
) - Cílový typ
new
není povolen s binárními operátory. - Je zakázáno, pokud neexistuje žádný typ, na který se má cílit: unární operátor, kolekce
foreach
, vusing
, v dekonstrukci, ve výrazuawait
, jako vlastnost anonymního typu (new { Prop = new() }
), v příkazulock
, vsizeof
, v příkazufixed
, v přístupu člena (new().field
), v dynamicky vyžádané operaci (someDynamic.Method(new())
), v dotazu LINQ, jako operand operátoruis
, jako levý operand operátoru??
, ... - Je také zakázáno jako
ref
. - Následující typy typů nejsou povoleny jako cíle převodu.
-
typy výčtu:
new()
bude fungovat (protoženew Enum()
funguje s výchozí hodnotou), alenew(1)
nebude fungovat, protože typy výčtu nemají konstruktor. - Typy rozhraní: To by fungovalo stejně jako odpovídající výraz pro vytváření pro typy modelu COM.
- typy polí: pole potřebují speciální zápis pro určení délky.
-
dynamické: nepovolujeme
new dynamic()
, takženew()
sdynamic
jako cílovým typem nepovolujeme. - n-tice: Mají stejný význam jako vytvoření objektu ze základního typu.
- Všechny ostatní typy, které nejsou povoleny v object_creation_expression jsou vyloučeny také, například typy ukazatelů.
-
typy výčtu:
Nevýhody
S cílovým typem new
vytváření zásadních změn v nových kategoriích vyvolalo určité obavy, ale už to máme s null
a default
, a to nebylo významným problémem.
Alternativy
Většina stížností na typy, které jsou příliš dlouhé na duplikování v inicializaci polí, se týká argumentů typu, jako jsou a, ne samotného typu. Mohli bychom odvodit pouze argumenty typu, jako je new Dictionary(...)
(nebo podobně), a odvodit argumenty typu místně z argumentů nebo inicializátoru kolekce.
Otázky
- Měli bychom zakázat použití ve stromech výrazů? (ne)
- Jak funkce komunikuje s
dynamic
argumenty? (žádné zvláštní zacházení) - Jak má IntelliSense fungovat s
new()
? (pouze pokud existuje jeden cílový typ)
Schůzky o designu
C# feature specifications