JavaScript支持类似于goto的语法来打破嵌套循环。一般来说,这不是一个好主意,但被认为是可以接受的做法。 C#不直接支持break labelName
语法...但是它确实支持臭名昭著的goto
。
我相信可以在C#中实现等效:
int i = 0;
while(i <= 10)
{
Debug.WriteLine(i);
i++;
for(int j = 0; j < 3; j++)
if (i > 5)
{
goto Break;//break out of all loops
}
}
Break:
按照JavaScript的相同逻辑,嵌套循环方案是
goto
的可接受用法吗?否则,我知道实现此功能的唯一方法是通过设置适当范围的bool
。 最佳答案
我的观点:带有嵌套循环的复杂代码流很难推理;分支,无论是goto还是break,都使它变得更加困难。首先,我会非常努力地思考是否有消除嵌套循环的方法,而不是编写goto。
几个有用的技术:
第一种技术:将内部循环重构为一种方法。让方法返回是否中断外循环。所以:
for(outer blah blah blah)
{
for(inner blah blah blah)
{
if (whatever)
{
goto leaveloop;
}
}
}
leaveloop:
...
变成
for(outer blah blah blah)
{
if (Inner(blah blah blah))
break;
}
...
bool Inner(blah blah blah)
{
for(inner blah blah blah)
{
if (whatever)
{
return true;
}
}
return false;
}
第二种方法:如果循环没有副作用,请使用LINQ。
// fulfill the first unfulfilled order over $100
foreach(var customer in customers)
{
foreach(var order in customer.Orders)
{
if (!order.Filled && order.Total >= 100.00m)
{
Fill(order);
goto leaveloop;
}
}
}
leaveloop:
相反,写:
var orders = from customer in customers
from order in customer.Orders;
where !order.Filled
where order.Total >= 100.00m
select order;
var orderToFill = orders.FirstOrDefault();
if (orderToFill != null) Fill(orderToFill);
无循环,因此无需中断。
另外,正如配置器在注释中指出的那样,您可以使用以下形式编写代码:
var orderToFill = customers
.SelectMany(customer=>customer.Orders)
.Where(order=>!order.Filled)
.Where(order=>order.Total >= 100.00m)
.FirstOrDefault();
if (orderToFill != null) Fill(orderToFill);
故事的寓意:循环强调控制流,但以业务逻辑为代价。与其尝试使越来越复杂的控制流相互叠加,不如尝试重构代码以使业务逻辑清晰明了。
关于c# - goto是否可以打破嵌套循环?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7882451/