不允许在 C# 的语句中使用短路函数调用?
Using short circuits function calls in statements in C# is not allowed?
我正在尝试在两个函数调用之间使用短路。以这段代码为例:
private void BubbleDown(Graph.Vertex item)
{
BubbleDownLeft(item) || BubbleDownRight(item);
}
其中 BubbleDownLeft
和 BubbleDownRight
都是 return 布尔值。这会引发以下错误:
Error CS0201 - Only assignment, call, increment, decrement, and new object expressions can be used as a statement
我知道我可以很容易地重写函数以使用 if 语句(但这不是那么漂亮)或者甚至只是将它分配给一个我不使用的值:
private void BubbleDown(Graph.Vertex item)
{
bool ignoreMe = BubbleDownLeft(item) || BubbleDownRight(item);
}
那么为什么我的第一个编码示例是错误的而不是有效的或者可能只是一个警告?
建议的代码对计算机没有意义。当您要求它 BubbleDown()
时,您告诉它 BubbleDownLeft()
或 BubbleDownRight()
但也忽略结果。编译器没有动机使用 short-circuit evaluation 因为无论如何结果都会被忽略。这种短路评估是 if 这是一个 if
语句的原因。
您在评论中声明:
I'll agree the extraneous ignoreMe
is worse than an if
, but the original is easily read. It clearly says that bubbleDown
is the result of either the left or the right. Going with the a, b, c, d, e, example, you would have to put if (!(a() || b() || c() || d())) e())
which would look like e() is the goal, but really it's a 5-branching path where the first path to succeed is taken.
这清楚地表明您想要进行短路评估,您的选择是更改 return 类型并执行:
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()
时简单地忽略 return 值,或者实际验证它确实如实执行了任何选项。
使用 C# 6 你可以更优雅:
private bool BubbleDown(Graph.Vertex item)
=> BubbleDownLeft(item) || BubbleDownRight(item);
但是,无论如何,您将通过这种方式更改方法 return 类型。
如果您严格来说想要像这样编码,而不更改 BubleDown
签名,您可以使用 C# 6 表达式主体函数做一些技巧:
private void BubbleDown(Graph.Vertex item)
=> BubbleDownImplementation(item);
private bool BubbleDownImplementation(Graph.Vertex item)
=> BubbleDownLeft(item) || BubbleDownRight(item);
另外,看看这个。
我正在尝试在两个函数调用之间使用短路。以这段代码为例:
private void BubbleDown(Graph.Vertex item)
{
BubbleDownLeft(item) || BubbleDownRight(item);
}
其中 BubbleDownLeft
和 BubbleDownRight
都是 return 布尔值。这会引发以下错误:
Error CS0201 - Only assignment, call, increment, decrement, and new object expressions can be used as a statement
我知道我可以很容易地重写函数以使用 if 语句(但这不是那么漂亮)或者甚至只是将它分配给一个我不使用的值:
private void BubbleDown(Graph.Vertex item)
{
bool ignoreMe = BubbleDownLeft(item) || BubbleDownRight(item);
}
那么为什么我的第一个编码示例是错误的而不是有效的或者可能只是一个警告?
建议的代码对计算机没有意义。当您要求它 BubbleDown()
时,您告诉它 BubbleDownLeft()
或 BubbleDownRight()
但也忽略结果。编译器没有动机使用 short-circuit evaluation 因为无论如何结果都会被忽略。这种短路评估是 if 这是一个 if
语句的原因。
您在评论中声明:
I'll agree the extraneous
ignoreMe
is worse than anif
, but the original is easily read. It clearly says thatbubbleDown
is the result of either the left or the right. Going with the a, b, c, d, e, example, you would have to putif (!(a() || b() || c() || d())) e())
which would look like e() is the goal, but really it's a 5-branching path where the first path to succeed is taken.
这清楚地表明您想要进行短路评估,您的选择是更改 return 类型并执行:
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()
时简单地忽略 return 值,或者实际验证它确实如实执行了任何选项。
使用 C# 6 你可以更优雅:
private bool BubbleDown(Graph.Vertex item)
=> BubbleDownLeft(item) || BubbleDownRight(item);
但是,无论如何,您将通过这种方式更改方法 return 类型。
如果您严格来说想要像这样编码,而不更改 BubleDown
签名,您可以使用 C# 6 表达式主体函数做一些技巧:
private void BubbleDown(Graph.Vertex item)
=> BubbleDownImplementation(item);
private bool BubbleDownImplementation(Graph.Vertex item)
=> BubbleDownLeft(item) || BubbleDownRight(item);
另外,看看这个