在C#语句中使用短路函数调用是不允许的?

时间:2016-02-29 22:10:17

标签: c# compiler-errors short-circuiting

我试图在两个函数调用之间使用短路。以此代码为例:

private void BubbleDown(Graph.Vertex item)
{
    BubbleDownLeft(item) || BubbleDownRight(item);
}

BubbleDownLeftBubbleDownRight都返回bool。这会引发以下错误:

  

错误CS0201 - 只能将赋值,调用,递增,递减和新对象表达式用作语句

我知道我可以轻松地重写函数以使用if语句(但这不是很漂亮),甚至只是将它分配给我不使用的值:

private void BubbleDown(Graph.Vertex item)
{
    bool ignoreMe = BubbleDownLeft(item) || BubbleDownRight(item);
}

那么为什么我的第一个编码示例是错误而不是有效或者只是警告?

2 个答案:

答案 0 :(得分:2)

建议的代码对计算机没有意义。当您向BubbleDown()提出要求时,请将其告知BubbleDownLeft()BubbleDownRight(),同时忽略结果。编译器没有动力使用short-circuit evaluation,因为无论如何都会忽略结果。这种短路评估是如果这是if声明的话。

在评论中,您声明:

  

我同意无关的ignoreMeif更糟糕,但原文很容易阅读。它清楚地表明bubbleDown是左或右的结果。使用a,b,c,d,e示例,您必须放置if (!(a() || b() || c() || d())) e())看起来像e()是目标,但实际上它是一个5分支路径,其中第一条路径成功被采取。

这清楚地表明您需要进行短路评估,您可以选择更改返回类型并执行以下操作:

private bool BubbleDown(Graph.Vertex item)
{
    return BubbleDownLeft(item) || BubbleDownRight(item);
}

或者您可以选择带有空块的if个参数。请注意;声明之后的if

private void BubbleDown(Graph.Vertex item)
{
   if (BubbleDownLeft(item) || BubbleDownRight(item)) ;
}

我想我更喜欢第一个,然后在调用BubbleDown()时忽略返回值,或者实际验证它实际上已经真实地执行了任何选项。

答案 1 :(得分:1)

使用C#6,你可以更优雅:

private bool BubbleDown(Graph.Vertex item)
    => BubbleDownLeft(item) || BubbleDownRight(item);

但是,无论如何,通过这种方式你可以改变方法返回类型。

如果您严格地想要编写这样的代码而不更改BubleDown签名,那么您可以使用C#6表达式身体函数做一些技巧:

private void BubbleDown(Graph.Vertex item)
    => BubbleDownImplementation(item);

private bool BubbleDownImplementation(Graph.Vertex item)
    => BubbleDownLeft(item) || BubbleDownRight(item);

此外,请查看此Eric Lippert answer