为什么不';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'

为什么不';t C#三元运算符与委托一起工作

问题是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,并且它将成功编译。