C# 内部断路开关不能终止于环路
我有一个代码片段:C# 内部断路开关不能终止于环路,c#,syntax,switch-statement,C#,Syntax,Switch Statement,我有一个代码片段: int n = 0; for (int i = 0; i < 50;i++) { n = checkStatus(); switch (n) { case 1: break; break;//This is unreachable and so i cannot Terminate the For Loop within the SWITCH } } 或者我很困惑 [POST] 我得
int n = 0;
for (int i = 0; i < 50;i++)
{
n = checkStatus();
switch (n)
{
case 1:
break;
break;//This is unreachable and so i cannot Terminate the For Loop within the SWITCH
}
}
或者我很困惑
[POST]
我得到了消息,问题解决了,但我想告诉大家,在for循环中使用Switch并不是一个好主意,因为我从很多开发人员那里听说,当我得到想要的结果时,我应该立即从循环中中断,所以使用Switch需要额外的布尔值,或者将Int I值推到50 direclty,但是如果我们使用while循环会发生什么呢?您可以使用,以便在开关中中断循环
int n = 0;
for (int i = 0; i < 50;i++)
{
n = checkStatus();
switch (n)
{
case 1:
goto outofloop;
}
}
:outofloop
// more code
int n=0;
对于(int i=0;i<50;i++)
{
n=检查状态();
开关(n)
{
案例1:
去外面;
}
}
:离开
//更多代码
goto
…为数不多的几个好用法之一,您可以使用布尔值
int n = 0;
for (int i = 0; i < 50; i++)
{
bool shouldBreak = false;
n = checkStatus();
switch (n)
{
case 1:
shouldBreak = true;
break;
}
if (shouldBreak)
break;
}
int n=0;
对于(int i=0;i<50;i++)
{
bool shouldBreak=false;
n=检查状态();
开关(n)
{
案例1:
shouldBreak=true;
打破
}
如果(应该中断)
打破
}
我不知道循环完成后是否需要执行其他逻辑,但您可以尝试使用return。另一个选项是设置布尔标志,并在切换后退出
switch (n)
{
case 1:
return;
}
你能把循环放在一个方法的内部并且只使用return吗
例如:
myLoopingMethod()
{
int n = 0;
for (int i = 0; i < 50;i++)
{
n = checkStatus();
switch (n)
{
case 1:
return;
}
}
}
myLoopingMethod()
{
int n=0;
对于(int i=0;i<50;i++)
{
n=检查状态();
开关(n)
{
案例1:
返回;
}
}
}
另一种选择是使用传统的if/else
而不是开关/case
。然后您可以使用break,它将跳出for
循环只需更改i的值:
int n = 0;
for (int i = 0; i < 50;i++)
{
n = checkStatus();
switch (n)
{
case 1:
i += 50;
break;
}
}
int n=0;
对于(int i=0;i<50;i++)
{
n=检查状态();
开关(n)
{
案例1:
i+=50;
打破
}
}
如果开关后没有其他代码
您只需检查for循环本身是否继续循环:
bool doContinue = true;
for (int i = 0; i < 50 && doContinue; i++)
{
n = checkStatus();
switch (n)
{
case 1:
doContinue = false;
}
}
bool doContinue=true;
对于(int i=0;i<50&&doContinue;i++)
{
n=检查状态();
开关(n)
{
案例1:
doContinue=false;
}
}
这种设计有点糟糕;有几种方法可以解决此问题:
如果您的交换机只有一种情况会断开外部环路,则只需在进入交换机之前检查:
if(n == 1)
break;
switch(n) { }
如果多个条件可以打破循环,则重构为更具linq风格的查询:
Enumerable.Range(0, 50).FirstOrDefault(x => listOfBreakCodes.Contains(checkStatus());
这将调用checkStatus
最多50次,直到遇到1(或其他中断代码),然后不再继续计算元素 解决方案1:将回路和开关移动到不同的方法:
for(int i = 0; i < 50; ++i)
{
if (DoCheckStatus(i)) break;
}
解决方案2:采用上述方法,通过一种急切的扩展方法消除循环:
static void DoWhile<T>(this IEnumerable<T> sequence, Func<T, bool> predicate)
{
foreach(T item in sequence)
if (!predicate(item)) return;
}
...
Enumerable.Range(0, 50).DoWhile(DoCheckStatus)
我假设您使用的是一个开关,因为您在代码示例中忽略了许多可能的n
值?是的,因为它是本机数据库,我不确定是否有n个值!使用i=50;或者将for()循环移动到一个helper函数中,这样就可以使用return。用一个回报而不是休息。为了对所有神圣事物的热爱,请不要建议这样。。。总有办法不使用goto
。这是我生存的祸根。@Chad-想解释一下为什么对goto
的本地化使用如此糟糕吗?@Oded它的草率。我还没有看到一些简单的重新分解不能消除使用goto
的倾向的情况。例如,将循环提取到一个方法并使用return
将消除对这个特定goto
@Chad的需要-“goto被认为是有害的”是在特定语言中滥用goto的遗留物。像任何其他编程构造一样,它也有它的位置。@Chad:“break”本身只是一个“goto”,它甚至不是一个goto,可以礼貌地标记它的目标!我同意可能有比嵌套在循环中的开关更优雅的代码结构方式,但在这个特殊的例子中,我没有任何问题,可以剥去伪装“break”与“goto”相同的薄贴面。是的,OP在他的问题中提到这是一个选项。不要认为当问题最初被问到的时候,这是一个选项,但不管怎样。+1表示消除控制流。LINQ版本比带有嵌套开关的循环更容易理解。。。更不用说更简洁了。只需记住,TakeWhile
是懒散的吹毛求疵:在样本上面“改编上面的内容”?非母语人士,但它不应该是“适应下面的情况”吗?@EricLippert除了break
之外,一个不同的用于从switch case
中断的关键字在这种情况下不会有帮助吗?为什么你们选择了break
作为回路和开关的案例?第一个问题的答案是“是”。第二个问题的答案太长,无法放入评论中,因此我建议你利用这是一个问答网站的事实,提出一个问题。真棒..+1,因为你与众不同
bool DoCheckStatus(int i)
{
switch(CheckStatus(i))
{
case 1 : return true;
default: return false;
}
}
static void DoWhile<T>(this IEnumerable<T> sequence, Func<T, bool> predicate)
{
foreach(T item in sequence)
if (!predicate(item)) return;
}
...
Enumerable.Range(0, 50).DoWhile(DoCheckStatus)
Enumerable.Range(0, 50).DoWhile(i=>
{
switch(CheckStatus(i))
{
case 1 : return true;
default: return false;
}
});