Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Espressioni tipate di destinazione
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. Quelle differenze vengono acquisite nelle note pertinenti ai language design meeting (LDM).
Altre informazioni sul processo per l'adozione di speclet di funzionalità nello standard del linguaggio C# sono disponibili nell'articolo sulle specifiche di .
Problema del campione: https://github.com/dotnet/csharplang/issues/100
Sommario
Non richiedere la specifica del tipo per i costruttori quando il tipo è noto.
Motivazione
Consenti inizializzazione dei campi senza duplicare il tipo.
Dictionary<string, List<int>> field = new() {
{ "item1", new() { 1, 2, 3 } }
};
Consente di omettere il tipo quando può essere dedotto dall'utilizzo.
XmlReader.Create(reader, new() { IgnoreWhitespace = true });
Creare un'istanza di un oggetto senza specificare il tipo.
private readonly static object s_syncObj = new();
Specificazione
Viene accettata una nuova forma sintattica, target_typed_new del object_creation_expression in cui il tipo è facoltativo.
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?
;
Un'espressione target_typed_new non dispone di un tipo. Tuttavia, esiste una nuova conversione di creazione di oggetti che è una conversione implicita da un'espressione, che va da un target_typed_new a ogni tipo.
Dato un tipo di destinazione T, il tipo T0 è il tipo sottostante di Tse T è un'istanza di System.Nullable. In caso contrario, T0 è T. Il significato di un'espressione target_typed_new convertita nel tipo T corrisponde al significato di un object_creation_expression corrispondente che specifica T0 come tipo.
Si tratta di un errore in fase di compilazione se un target_typed_new viene usato come operando di un operatore unario o binario o se viene usato in cui non è soggetto a una conversione di creazione di oggetti .
Problema aperto: dovremmo consentire delegati e tuple come tipo obiettivo?
Le regole precedenti includono delegati (un tipo di riferimento) e tuple (un tipo struct). Anche se entrambi i tipi sono costruttibili, se il tipo è inferibile, è già possibile usare una funzione anonima o un valore letterale di tupla.
(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
Misto
Di seguito sono riportate le conseguenze della specifica:
-
throw new()è consentito (il tipo di destinazione èSystem.Exception) - L'
newtipizzato di destinazione non è consentito con operatori binari. - Non è consentito quando non esiste alcun tipo di destinazione: operatori unari, raccolta di un
foreach, in unusing, in una decostruzione, in un'espressioneawait, come proprietà di tipo anonimo (new { Prop = new() }), in un'istruzionelock, in unsizeof, in un'istruzionefixed, in un accesso membro (new().field), in un'operazione gestita dinamicamente (someDynamic.Method(new())), in una query LINQ, come operando dell'operatoreis, come operando sinistro dell'operatore??, ... - Non è consentito anche come
ref. - I tipi seguenti non sono consentiti come destinazioni della conversione
-
tipi di enumerazione:
new()funzionerà (comenew Enum()funziona per assegnare il valore predefinito), manew(1)non funzionerà poiché i tipi di enumerazione non dispongono di un costruttore. - Tipi di interfaccia: questa operazione funziona come l'espressione di creazione corrispondente per i tipi COM.
- Tipi di matrice: matrici necessitano di una sintassi speciale per fornire la lunghezza.
-
dinamica: non consentiamo
new dynamic(), quindi non consentiamonew()condynamiccome tipo di destinazione. - tuple: hanno lo stesso significato della creazione di un oggetto usando il tipo sottostante.
- Tutti gli altri tipi non consentiti nel object_creation_expression vengono esclusi anche, ad esempio, tipi di puntatore.
-
tipi di enumerazione:
Svantaggi
Ci sono state alcune preoccupazioni riguardo alla creazione di nuove categorie di modifiche significative con il tipo di destinazione new, ma questo lo avevamo già con null e default, e non è stato un problema significativo.
Alternative
La maggior parte delle lamentele relative ai tipi troppo lunghi da duplicare nell'inizializzazione dei campi riguarda gli argomenti di tipo , non il tipo stesso; potremmo dedurre solo argomenti di tipo come new Dictionary(...) (o simili) e dedurre localmente gli argomenti di tipo dagli argomenti o dall'inizializzatore della raccolta.
Domande
- È consigliabile proibire gli utilizzi negli alberi delle espressioni? (no)
- In che modo la funzionalità interagisce con gli argomenti
dynamic? (nessun trattamento speciale) - Come funziona IntelliSense con
new()? (solo quando è presente un singolo tipo di destinazione)
Riunioni di design
C# feature specifications