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:
Run Code Online (Sandbox Code Playgroud)
通过JavaScript的相同逻辑,嵌套循环场景是否可以接受goto?否则,我知道实现此功能的唯一方法是设置bool适当的范围.
Eri*_*ert 28
我的观点:使用嵌套循环的复杂代码流很难推理; 分支,无论是goto还是break,都会让它变得更难.我不会写goto,而是首先想到是否有办法消除嵌套循环.
一些有用的技巧:
第一种技术:将内循环重构为方法.让方法返回是否突破外循环.所以:
for(outer blah blah blah)
{
for(inner blah blah blah)
{
if (whatever)
{
goto leaveloop;
}
}
}
leaveloop:
...
Run Code Online (Sandbox Code Playgroud)
变
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;
}
Run Code Online (Sandbox Code Playgroud)
第二种技术:如果循环没有副作用,请使用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:
Run Code Online (Sandbox Code Playgroud)
相反,写:
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);
Run Code Online (Sandbox Code Playgroud)
没有循环,因此不需要突破.
或者,正如配置程序在注释中指出的那样,您可以使用以下格式编写代码:
var orderToFill = customers
.SelectMany(customer=>customer.Orders)
.Where(order=>!order.Filled)
.Where(order=>order.Total >= 100.00m)
.FirstOrDefault();
if (orderToFill != null) Fill(orderToFill);
Run Code Online (Sandbox Code Playgroud)
故事的寓意:循环强调控制流程而牺牲业务逻辑.而不是试图堆在彼此顶部越来越复杂的控制流程,尝试重构代码,使业务逻辑清晰.
Jon*_*eet 12
我个人试图通过简单地将循环放入不同的方法来避免在这里使用goto - 虽然你不能轻易地突破特定级别的循环,但你可以在任何时候轻松地从方法返回.
根据我的经验,这种方法通常会导致更简单,更易读的代码和更短的方法(做一个特定的工作).
slu*_*ter 11
让我们直截了当:使用该goto语句没有任何根本性的错误,它不是邪恶的 - 它只是工具箱中的另一个工具.它是如何使用它真正重要的,它很容易被误用.
打破某些描述的嵌套循环可以有效地使用该语句,但您应首先查看它是否可以重新设计.您的循环退出表达式可以重写吗?你使用适当类型的循环?您是否可以过滤可能迭代的数据列表,以便您不需要提前退出?你应该将一些循环代码重构为一个单独的函数吗?