为什么不';t C#三元运算符与委托一起工作
本文关键字:运算符 三元 工作 一起 为什么不 | 更新日期: 2023-09-27 18:26:40
当分支选择函数时,使用三元运算符选择函数可能是有意义的,但这是不可能的。为什么?
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;
中,上下文并不那么容易。三元运算符首先尝试将demo1
的类型与demo2
的类型相匹配,但这是另一个方法组,因此没有任何帮助。编译器没有超越预期并失败。
解决方案是明确方法组预期的类型:
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
,并且它将成功编译。