2012-07-03 8 views
18

Sto provando a utilizzare l'operatore condizionale (ternario) per assegnare l'espressione lambda corretta a una variabile, a seconda di una condizione, ma ottengo l'errore del compilatore: Tipo di l'espressione condizionale non può essere determinata perché non esiste una conversione implicita tra "espressione lambda" e "espressione lambda". Posso usare il normale if-else per risolvere questo problema, ma l'operatore condizionale ha più senso per me (in questo contesto), renderebbe il codice più conciso aggiungere, almeno, mi piacerebbe sapere i motivi per cui non lo fa lavoro.Assegnare un'espressione lambda usando l'operatore condizionale (ternario)

// this code compiles, but is ugly! :) 
Action<int> hh; 
if (1 == 2) hh = (int n) => Console.WriteLine("nope {0}", n); 
else hh = (int n) => Console.WriteLine("nun {0}", n); 

// this does not compile 
Action<int> ff = (1 == 2) 
    ? (int n) => Console.WriteLine("nope {0}", n) 
    : (int n) => Console.WriteLine("nun {0}", n); 
+0

Grazie per la tua rapidità rich.okelly, Nikhil Agrawal, Romain Verdier e Alex! Tutte le tue risposte sono state corrette (compilare e dare il risultato corretto), ma la mia scelta va a rich.okelly a causa della sua spiegazione. –

risposta

18

il compilatore C# tenta di creare il lambda in modo indipendente e non può inequivocabilmente determinare il tipo.Casting in grado di informare il compilatore quale tipo da utilizzare:

Action<int> ff = (1 == 2) 
    ? (Action<int>)((int n) => Console.WriteLine("nope {0}", n)) 
    : (Action<int>)((int n) => Console.WriteLine("nun {0}", n)); 
15

Questo funzionerà.

Action<int> ff = (1 == 2) 
? (Action<int>)((int n) => Console.WriteLine("nope {0}", n)) 
: (Action<int>)((int n) => Console.WriteLine("nun {0}", n)); 

Ci sono due problemi qui

  1. Espressione
  2. ternario Operatore

1. Problema con Expression

il compilatore dicendoti esattamente cosa c'è che non va - 'Type of conditional expression cannot be determined because there is no implicit conversion between 'lambda expression' and 'lambda expression'.

Significa che cosa hai scritto è espressione lambda e la variabile risultante è anche espressione lambda.

L'espressione lambda non ha alcun tipo particolare: è solo convertibile nell'albero delle espressioni.

Un'espressione membro di accesso (che è quello che stai cercando di fare) è disponibile solo nelle forme

primary-expression . identifier type-argument-list(opt) 
predefined-type . identifier type-argument-list(opt) 
qualified-alias-member . identifier type-argument-list(opt) 

... e un'espressione lambda non è un'espressione primaria.

2. Problema con ternario Operatore

Se facciamo

bool? br = (1 == 2) ? true: null; 

Ciò si traduce in errore che dice esattamente come la tua. 'Type of conditional expression cannot be determined because there is no implicit conversion between 'bool' and '<null>'

Ma l'errore è andato se facciamo questo

bool? br = (1 == 2) ? (bool?)true: (bool?)null; 

Fusione di un lato funziona anche

bool? br = (1 == 2) ? (bool?)true: null; 

O

bool? br = (1 == 2) ? true: (bool?)null; 

Per il vostro caso

Action<int> ff = (1 == 2) 
? (Action<int>)((int n) => Console.WriteLine("nope {0}", n)) 
: ((int n) => Console.WriteLine("nun {0}", n)); 

O

Action<int> ff = (1 == 2) 
? ((int n) => Console.WriteLine("nope {0}", n)) 
: (Action<int>)((int n) => Console.WriteLine("nun {0}", n)); 
+0

+1 veloce e perfetto – Habib

+0

ottima risposta, direttamente al punto con esempi chiari ... grazie – Dal

+0

@Dal: Grazie. :) –

3

In sostanza la stessa risposta come gli altri, in una forma diversa

Action<int> ff = (1 == 2) 
? new Action<int>(n => Console.WriteLine("nope {0}", n)) 
: new Action<int>(n => Console.WriteLine("nun {0}", n)); 
4

Infatti, con inferenza di tipo, è possibile:

  • Utilizzare var per la variabile locale
  • Solo trasmettere la prima espressione dell'operatore ternario
  • Ometti il ​​tipo del parametro lambda poiché può essere dedotto

Il risultato è molto più conciso. (Ti lascio decidere se è più leggibile.)

var ff = condition 
      ? (Action<int>)(n => Console.WriteLine("nope {0}", n)) 
      : n => Console.WriteLine("nun {0}", n); 
Problemi correlati