Target-Typed'espressione condizionale
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 acquisite nelle pertinenti note della riunione per la progettazione del linguaggio (LDM)
Puoi saperne di più sul processo di adozione degli speclet delle funzionalità nello standard del linguaggio C# nell'articolo sulle specifiche di .
Conversione di espressioni condizionali
Per un'espressione condizionale c ? e1 : e2
, quando
- non esiste un tipo comune per
e1
ee2
o - per cui esiste un tipo comune, ma una delle espressioni
e1
oe2
non ha alcuna conversione implicita in tale tipo
Definiamo una nuova conversione implicita dell'espressione condizionale che consente una conversione implicita dall'espressione condizionale a qualsiasi tipo T
per cui è presente una conversione da espressione da e1
a T
e anche da e2
a T
. Si tratta di un errore se un'espressione condizionale non ha un tipo comune tra e1
e e2
né è soggetta a una conversione dell'espressione condizionale .
Conversione migliore dell'espressione
Cambiamo
Miglior conversione di un'espressione
Data una conversione implicita
C1
che esegue la conversione da un'espressioneE
a un tipoT1
e una conversione implicitaC2
che converte da un'espressioneE
a un tipoT2
,C1
è una conversione migliore rispetto aC2
seE
non corrisponde esattamente aT2
e almeno una delle seguenti condizioni:
a
Conversione migliore dall'espressione
Data una conversione implicita
C1
che converte da un'espressioneE
a un tipoT1
, e una conversione implicitaC2
che converte da un'espressioneE
a un tipoT2
,C1
è una conversione migliore rispetto aC2
seE
non corrisponde esattamente aT2
e almeno una delle seguenti condizioni è soddisfatta:
E
corrisponde esattamenteT1
(§12.6.4.5)C1
non è una conversione di espressioni condizionali eC2
è una conversione di espressioni condizionali .T1
è una destinazione di conversione migliore rispetto aT2
(§12.6.4.7) eC1
eC2
sono entrambe conversioni di espressioni condizionali o nessuno dei due è una conversione di espressioni condizionali .
Espressione cast
La specifica del linguaggio C# corrente indica
Un cast_expression della forma
(T)E
, doveT
è un tipo eE
è un unary_expression, esegue una conversione esplicita (§10.3) del valore diE
al tipoT
.
In presenza della conversione dell'espressione condizionale potrebbero esserci più di una possibile conversione da E
a T
. Con l'aggiunta della conversione dell'espressione condizionale , si preferisce qualsiasi altra conversione a una conversione dell'espressione condizionale e si usa la conversione dell'espressione condizionale solo come ultima risorsa.
Note sulla progettazione
Il motivo della modifica a Conversione migliore dall'espressione consiste nel gestire un caso come questo:
M(b ? 1 : 2);
void M(short);
void M(long);
Questo approccio presenta due piccoli svantaggi. In primo luogo, non è esattamente uguale all'espressione switch:
M(b ? 1 : 2); // calls M(long)
M(b switch { true => 1, false => 2 }); // calls M(short)
Questo è ancora un cambiamento di rilievo, ma il suo ambito è meno probabile che influisca sui programmi reali:
M(b ? 1 : 2, 1); // calls M(long, long) without this feature; ambiguous with this feature.
M(short, short);
M(long, long);
Ciò diventa ambiguo perché la conversione in long
è migliore per il primo argomento (perché non usa la conversione dell'espressione condizionale ), ma la conversione in short
è migliore per il secondo argomento (perché short
è una destinazione di conversione migliore rispetto a long
). Questa modifica di rilievo sembra meno grave perché non modifica il comportamento di un programma esistente in modo silenzioso.
Il motivo per cui le note sull'espressione di cast è quello di gestire un caso come questo:
_ = (short)(b ? 1 : 2);
Questo programma usa attualmente la conversione esplicita da int
a short
e si vuole mantenere il significato corrente del linguaggio di questo programma. La modifica non sarebbe osservabile in fase di esecuzione, ma con il programma seguente la modifica sarebbe osservabile:
_ = (A)(b ? c : d);
dove c
è di tipo C
, d
è di tipo D
e esiste una conversione implicita definita dall'utente da C
a D
e una conversione implicita definita dall'utente da D
a A
e una conversione implicita definita dall'utente da C
a A
. Se questo codice viene compilato prima di C# 9.0, quando b
è true, viene eseguita la conversione da c
a D
quindi in A
. Se usiamo la conversione dell'espressione condizionale , allora, quando b
è vero, convertiamo direttamente da c
a A
, il che comporta l'esecuzione di una sequenza diversa di codice utente. Di conseguenza, trattiamo la conversione dell'espressione condizionale come ultima risorsa in un cast, per mantenere il comportamento esistente.
C# feature specifications