Condividi tramite


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

  1. non esiste un tipo comune per e1 e e2o
  2. per cui esiste un tipo comune, ma una delle espressioni e1 o e2 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'espressione E a un tipo T1e una conversione implicita C2 che converte da un'espressione E a un tipo T2, C1 è una conversione migliore rispetto a C2 se E non corrisponde esattamente a T2 e almeno una delle seguenti condizioni:

  • E corrisponde esattamente T1 (§12.6.4.5)
  • T1 è una destinazione di conversione migliore rispetto a T2 (§12.6.4.7)

a

Conversione migliore dall'espressione

Data una conversione implicita C1 che converte da un'espressione E a un tipo T1, e una conversione implicita C2 che converte da un'espressione E a un tipo T2, C1 è una conversione migliore rispetto a C2 se E non corrisponde esattamente a T2 e almeno una delle seguenti condizioni è soddisfatta:

  • E corrisponde esattamente T1 (§12.6.4.5)
  • C1 non è una conversione di espressioni condizionali e C2 è una conversione di espressioni condizionali .
  • T1 è una destinazione di conversione migliore rispetto a T2 (§12.6.4.7) e C1 e C2 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, dove T è un tipo e E è un unary_expression, esegue una conversione esplicita (§10.3) del valore di E al tipo T.

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 shorte 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 De esiste una conversione implicita definita dall'utente da C a De una conversione implicita definita dall'utente da D a Ae 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.