Condividi tramite


Consenti l'uso della direttiva alias per fare riferimento a qualsiasi tipo di tipo

Nota

Questo articolo è una specifica di funzionalità. La specifica funge da documento di progettazione per la funzionalità. Include le modifiche specifiche proposte, insieme alle informazioni necessarie durante la progettazione e lo sviluppo della funzionalità. Questi articoli vengono pubblicati fino a quando le modifiche specifiche proposte non vengono completate e incorporate nella specifica ECMA corrente.

Potrebbero verificarsi alcune discrepanze tra la specifica di funzionalità e l'implementazione completata. Tali differenze vengono riportate nelle note pertinenti della riunione sul design del linguaggio (LDM) .

Puoi trovare ulteriori informazioni sul processo di adozione degli speclet delle funzionalità nello standard del linguaggio C# nell'articolo sulle specifiche di .

Problema del campione: https://github.com/dotnet/csharplang/issues/8645

Sommario

Allenta la direttiva using_alias_directive (§13.5.2) per consentirle di puntare a qualsiasi tipo, non solo ai tipi nominati. Questo permetterebbe l'utilizzo di tipi non consentiti oggi, come: tipi di tupla, tipi di puntatore, tipi di matrice, eccetera. Ad esempio, questo ora sarebbe consentito:

using Point = (int x, int y);

Motivazione

Da tempo, C# ha avuto la possibilità di introdurre alias per namespace e tipi con nome (classi, delegate, interfacce, record e struct). Questo ha funzionato in modo accettabilmente bene in quanto ha fornito un mezzo per introdurre nomi non in conflitto nei casi in cui un nome comune proveniente da using_directives potrebbe essere ambiguo, e ha permesso di fornire un nome più semplice nel gestire tipi generici complessi. Tuttavia, l'aumento di simboli di tipi complessi aggiuntivi nel linguaggio ha causato un uso maggiore in cui gli alias sarebbero utili ma non sono attualmente consentiti. Ad esempio, sia le tuple che i puntatori a funzione spesso possono avere forme testuali regolari grandi e complesse che possono essere dolorose da scrivere continuamente e un onere per provare a leggere. Gli alias potrebbero essere utili in questi casi assegnando un nome breve, fornito dallo sviluppatore, che può quindi essere usato al posto di tali forme strutturali complete.

Progettazione dettagliata

La grammatica di using_alias_directive verrà modificata in modo da:

using_alias_directive
-    : 'using' identifier '=' namespace_or_type_name ';'
+    : 'using' identifier '=' (namespace_name | type) ';'
    ;

Le annotazioni di nullabilità del tipo di riferimento di primo livello non sono consentite.

È interessante notare che la maggior parte della lingua specifica in §13.5.2 non deve cambiare. La maggior parte della lingua in essa fa già riferimento a "spazio dei nomi o tipo", ad esempio:

Un using_alias_directive introduce un identificatore che funge da alias per uno spazio dei nomi o un tipo all'interno dell'unità di compilazione o del corpo dello spazio dei nomi che lo racchiude immediatamente.

Questo rimane vero, solo che ora la grammatica consente al "tipo" di essere di qualsiasi tipo arbitrario, non il set limitato consentito in precedenza da namespace_or_type_name.

Le sezioni che richiedono l'aggiornamento sono:

- The order in which using_alias_directives are written has no significance, and resolution of the namespace_or_type_name referenced by a using_alias_directive is not affected by the using_alias_directive itself or by other using_directives in the immediately containing compilation unit or namespace body. In other words, the namespace_or_type_name of a using_alias_directive is resolved as if the immediately containing compilation unit or namespace body had no using_directives. A using_alias_directive may however be affected by extern_alias_directives in the immediately containing compilation unit or namespace body. In the example
+ The order in which using_alias_directives are written has no significance, and resolution of the `(namespace_name | type)` referenced by a using_alias_directive is not affected by the using_alias_directive itself or by other using_directives in the immediately containing compilation unit or namespace body. In other words, the `(namespace_name | type)` of a using_alias_directive is resolved as if the immediately containing compilation unit or namespace body had no using_directives. A using_alias_directive may however be affected by extern_alias_directives in the immediately containing compilation unit or namespace body. In the example
- The namespace_name referenced by a using_namespace_directive is resolved in the same way as the namespace_or_type_name referenced by a using_alias_directive. Thus, using_namespace_directives in the same compilation unit or namespace body do not affect each other and can be written in any order.
+ The namespace_name referenced by a using_namespace_directive is resolved in the same way as the namespace_or_type_name referenced by a using_alias_directive. Thus, using_namespace_directives in the same compilation unit or namespace body do not affect each other and can be written in any order.
+ It is illegal for a using alias type to be a nullable reference type.

    1. `using X = string?;` is not legal.
    2. `using X = List<string?>;` is legal.  The alias is to `List<...>` which is itself not a nullable reference type itself, even though it contains one as a type argument.
    3. `using X = int?;` is legal.  This is a nullable *value* type, not a nullable *reference* type.

Supporto degli alias ai tipi contenenti puntatori.

Un nuovo contesto non sicuro viene aggiunto tramite una parola chiave facoltativa "unsafe" nella produzione using_alias_directive:

using_alias_directive
+    : 'using' 'unsafe'? identifier '=' (namespace_name | type) ';'
    ;
    
using_static_directive
+    : 'using' 'static' 'unsafe'? type_name ';'
    ;

+ 'unsafe' can only be used with an using_alias_directive or using_static_directive, not a using_directive.
+ The 'unsafe' keyword present in a 'using_alias_directive' causes the entire textual extent of the 'type' portion (not the 'namespace_name' portion) to become an unsafe context. 
+ The 'unsafe' keyword present in a 'using_static_directive' causes the entire textual extent of the 'type_name' portion to become an unsafe context.