2016-01-06 34 views
2

我刚刚开始工作,在工作日结束时,我通过慢慢阅读我们的代码库来等待流量。我遇到了这一点,即使在白板上花了相当长的时间,我依然想不到一种方法来提取goto。有没有办法消除这种跳跃?我该如何摆脱这个goto?

public void MyUpdate(MyType foo) 
{ 
    /*Prep code for the loops*/   
    foreach (Thing bar in something) 
    { 
     foreach (Collection item in bar.Stuff) 
     { 
      Data dataRX = item.First; 
      if (dataRX != null && dataRX.ID.Equals(globalNonsense.ID)) 
      { 
       // Update Data with the latest changes 
       dataRX.fooBuddy = foo; 
       goto exitLoops; 
      } 
     } 
    } 

    exitLoops: ; 
} 
+3

为什么不'return'如果'exitLoops'是在方法的结束? –

+0

@YacoubMassad好主意,但在某些编码标准中,从一个函数中的多个位置返回''''会被认为是不好的形式,如goto。 –

+1

我更喜欢'return'解决方案。上面提到的代码标准也不像我的答案那样喜欢“break”。但我认为这些标准往往是非常理论化的,在这种情况下不应该被认为是严肃的。 –

回答

6

由于标签exitLoops是在方法结束,那么你可以简单地使用return退出方法是这样的:

if (dataRX != null && dataRX.ID.Equals(globalNonsense.ID)) 
{ 
    // Update Data with the latest changes 
    dataRX.fooBuddy = foo; 
    return; 
} 

另一种方法是使用这样的标志:

bool done = false; 

foreach (Thing bar in something) 
{ 
    foreach (Collection item in bar.Stuff) 
    { 
     Data dataRX = item.First; 
     if (dataRX != null && dataRX.ID.Equals(globalNonsense.ID)) 
     { 
      // Update Data with the latest changes 
      dataRX.fooBuddy = foo; 
      done = true; 
      break; 
     } 
    } 

    if(done) 
     break; 
} 

即使标签后面有一些代码,也可以使用第二种方法。

+1

现在你指出了,“返回”似乎非常明显。 exitLoops标签之后过去有很多空白空间,我敢打赌在这个函数中曾经有过更多的代码。谢谢。 – HireThisMarine

3

将内部循环移到方法中,并根据其返回值有条件地中断。

2

这不是那么好,但没有实现一个完整的新算法,这似乎是最简单的方法:

foreach (Thing bar in something) 
{ 
    bool exitLoop = false; 
    foreach (Collection item in bar.Stuff) 
    { 
     Data dataRX = item.First; 
     if (dataRX != null && dataRX.ID.Equals(globalNonsense.ID)) 
     { 
      // Update Data with the latest changes 
      dataRX.fooBuddy = foo; 
      exitLoop = true; 
      break; 
     } 
    } 

    if (exitLoop) break; 
} 
1

或者,您也可以做到这一点使用LINQ:

public void MyUpdate(MyType foo) 
{ 
    Thing dummy = something.FirstOrDefault(bar => bar.Stuff.SkipWhile((item) => 
    { 
     Data dataRx = item.First; 
     if (dataRx != null && dataRx.ID.Equals(globalNonsense.ID)) 
     { 
      dataRx.fooBuddy = foo; 
      return false; 
     } 
     else 
     { 
      return true; 
     } 
    }).Count() != 0); 
}