2012-07-03 23 views
18

Koşullara bağlı olarak bir değişkene doğru lambda ifadesini atamak için koşullu (üçlü) operatörü kullanmaya çalışıyorum ama derleyici hatası alıyorum: koşullu ifade belirlenemiyor çünkü 'lambda ifadesi' ve 'lambda ifadesi' arasında örtük bir dönüşüm yoktur. Bu problemi çözmek için normal olanı kullanabilirim, fakat koşullu operatör benim için daha mantıklı (bu bağlamda), kodu daha özlü bir hale getirecektir, en azından, neden olmasın diye bilmek istiyorum. Çalış.Koşullu (üçlü) işleç kullanarak bir lambda ifadesi atama

// 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

4 Huzurunuz için teşekkür ederiz. Rich.okelly, Nikhil Agrawal, Romain Verdier ve Alex! Bütün cevaplarınız doğruydu (derleme ve doğru sonucu ver), ama seçimim onun açıklaması nedeniyle rich.okelly'e gidiyor. –

cevap

18

C# derleyicisi bağımsız lambdas oluşturmaya çalışır ve açık bir türü belirleyemez.tür kesmesi ile farklı bir formda Aslında

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

Bu işe yarayacaktır.

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

burada iki sorun

  1. İfade
  2. Üçlü Operatör İfade ile

1. Sorun var

derleyici toplamak vardır tam olarak neyin yanlış olduğunu söylüyorum - 'Type of conditional expression cannot be determined because there is no implicit conversion between 'lambda expression' and 'lambda expression'. Yazdığınız şey lambda ifadesidir ve ortaya çıkan değişken de lambda ifadesidir.

Lambda ifadesinin herhangi bir türü yok - yalnızca ifade ağacına dönüştürülebilir.

(eğer yapmaya çalıştığını ne) üyesi erişim ifade biçimlerinin

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

yalnızca kullanılabilir ... ve bir lambda ifadesi birincil ifadesi değildir. Tam olarak sizin gibi diyerek bu hataya yol açar

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

yaparsanız Üçlü Operatör

ile

2. Sorunu. Biz bir taraftan bu

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

Döküm da durum için

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

VEYA

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

çalışacak yaparsak

Ama hata 'Type of conditional expression cannot be determined because there is no implicit conversion between 'bool' and '<null>' gitmiş

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

TD

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

+1 hızlı ve mükemmel – Habib

+0

mükemmel cevap, temiz örneklerle noktaya ... teşekkürler – Dal

+0

@Dal: Teşekkürler. :) –

3

diğerleri gibi aynı cevabı şunları yapabilirsiniz:: Kullanılacak tipi derleyici bilgilendirebilir Döküm

    yerel değişken için
  • kullanın var
  • Sadece üçlü operatörün ilk ifadesini döküm
  • Çıktı olabileceğinden, lambda parametresinin türünü belirtme

Sonuç çok daha kısadır. (Daha okunabilir olup olmadığına karar vermenize izin veririm.)

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

yılında, Temelde

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