为什么C#三元运算符不能与代理一起使用?

分支选择函数时,使用三元运算符选择函数可能是有意义的,但这是不可能的。 为什么?

public class Demo { protected bool branch; protected void demo1 () {} protected void demo2 () {} public Action DoesntWork() { return branch ? demo1 : demo2; } } 

编译器产生以下错误:

 Cannot implicitly convert type `method group' to `System.Action' 

问题是demo1不是一个简单的表达式,它是一种方法 。 并且方法可以被覆盖,因此它实际上不是一个方法,它是一个方法组 。 请考虑以下示例:

 public class Demo { protected bool branch; protected void demo1 (int) {} protected void demo1 () {} protected void demo2 () {} public Action DoesntWork() { return branch ? demo1 : demo2; //Error return demo1; //ok } } 

现在, demo1被重载了,那么应该使用哪两个版本? 答案是通过使用使用函数的上下文来选择重载函数。

return demo1很明显,它需要一个Action

但在return branch? demo1 : demo2; return branch? demo1 : demo2; 上下文并不那么容易。 三元运算符首先尝试将demo1的类型与demo1的类型进行匹配,但这是另一个方法组,因此没有任何帮助。 编译器不会超越并失败。

解决方案是清除方法组中预期的类型:

 return branch? new Action(demo1) : demo2; return branch? (Action)demo1 : demo2; Action d1 = demo1; return branch? d1 : demo2; 

您必须显式创建适当类型的委托。 通常,您可以使用demo1来引用System.Action ,但这只是因为编译器可以根据用法推断出类型并为您创建委托。 在这种情况下,编译器在三元运算符中使用时不知道您的方法应该转换为System.Action

如果您自己提供这个参数甚至其中一个参数,它将起作用:

 public Action DoesWork() { return branch ? demo1 : new Action(demo2); } 

由于这会为一个参数显式返回new Action ,因此编译器可以推断另一个应该转换为适合System.Action ,并且它将成功编译。