22

条件 (三項) 演算子を使用して、条件に応じて適切なラムダ式を変数に代入しようとしていますが、コンパイラ エラーが発生します。 ' および 'ラムダ式' . 通常の if-else を使用してこの問題を解決できますが、条件演算子は (このコンテキストでは) 私にとってはより理にかなっており、コードをより簡潔に追加できます。少なくとも、そうでない理由を知りたいです。動作しません。

// 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);
4

4 に答える 4

23

C#コンパイラは、ラムダを個別に作成しようとしますが、タイプを明確に判別することはできません。キャストは、使用するタイプをコンパイラーに通知できます。

Action<int> ff = (1 == 2)
  ? (Action<int>)((int n) => Console.WriteLine("nope {0}", n))
  : (Action<int>)((int n) => Console.WriteLine("nun {0}", n));
于 2012-07-03T11:05:05.857 に答える
16

これは機能します。

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

ここには2つの問題があります

  1. 表現
  2. 三項演算子

1.表現の問題

コンパイラは何が悪いのかを正確に教えてくれます- 'Type of conditional expression cannot be determined because there is no implicit conversion between 'lambda expression' and 'lambda expression'

これは、あなたが書いたものがラムダ式であり、結果の変数もラムダ式であることを意味します。

ラムダ式には特定のタイプはありません。式ツリーに変換できるだけです。

メンバーアクセス式(これはあなたがやろうとしていることです)はフォームでのみ利用可能です

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

...そしてラムダ式はプライマリ式ではありません。

2.三項演算子の問題

もしそうなら

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

これにより、あなたとまったく同じように言ってエラーが発生します。'Type of conditional expression cannot be determined because there is no implicit conversion between 'bool' and '<null>'

しかし、これを行うとエラーはなくなります

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

片面のキャスティングも機能します

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

また

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

あなたの場合

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

また

Action<int> ff = (1 == 2)
? ((int n) => Console.WriteLine("nope {0}", n))
: (Action<int>)((int n) => Console.WriteLine("nun {0}", n)); 
于 2012-07-03T11:04:04.343 に答える
6

実際、型推論を使用すると、次のことができます。

  • ローカル変数に var を使用する
  • 三項演算子の最初の式のみをキャストする
  • 推論できるため、ラムダ パラメータの型を省略します。

結果ははるかに簡潔です。(読みやすいかどうかはあなたに決めてもらいます。)

    var ff = condition 
             ? (Action<int>)(n => Console.WriteLine("nope {0}", n)) 
             : n => Console.WriteLine("nun {0}", n);
于 2012-07-03T11:14:23.777 に答える
5

基本的には他の方と同じ回答ですが、形は違います

Action<int> ff = (1 == 2) 
? new Action<int>(n => Console.WriteLine("nope {0}", n)) 
: new Action<int>(n => Console.WriteLine("nun {0}", n));
于 2012-07-03T11:09:33.730 に答える