22

我正在尝试使用条件(三元)运算符将正确的 lambda 表达式分配给变量,具体取决于条件,但我得到编译器错误:无法确定条件表达式的类型,因为 'lambda 表达式之间没有隐式转换' 和 'lambda 表达式'。我可以使用常规的 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# 编译器尝试独立创建 lambda,并且无法明确确定类型。强制转换可以通知编译器使用哪种类型:

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

这里有两个问题

  1. 表达
  2. 三元运算符

1. 表达问题

编译器准确地告诉你出了什么问题 - 'Type of conditional expression cannot be determined because there is no implicit conversion between 'lambda expression' and 'lambda expression'

这意味着您编写的是 lambda 表达式,结果变量也是 lambda 表达式。

lambda 表达式没有任何特定类型 - 它只是可转换为表达式树。

成员访问表达式(这是您尝试做的)仅在表单中可用

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

...并且 lambda 表达式不是主要表达式。

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 作为局部变量
  • 只转换三元运算符的第一个表达式
  • 省略 lambda 参数的类型,因为它可以被推断出来

结果更加简洁。(我让你决定它是否更具可读性。)

    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 回答