2011-07-20 27 views
0

在Java中,它是這樣寫的。當我移植這個代碼時...意識到沒有這樣的東西,如 break <label>continue <label>如何在C#中重寫Java [繼續<label>並打破<label>]?

我知道這些命令不包括在內,因爲必須有使用帶有命令轉到當這樣做的更清潔的方式..

但最後我用下面..任何方式的C#代碼重寫它更清潔?

Java代碼的

for(JClass c : classes) { 
    for(JMethod m : c.getMethods()) { 
     JCode code = m.getCode(); 
     if(code == null) 
      continue; 
     label: for(int index = 0; index < code.getExceptionLookupTable().length; index++) { 
      JException e = code.getExceptionTable().get(index); 
      for(int index2 = e.getStartIndex(); index2 < e.getEndIndex(); index2++) 
       if(code.getInstruction(index2).getOpcode() == NEW && ((NEW) code.getInstruction(index2)).getType().equals("java/lang/RuntimeException")) 
        continue label; 
       if(e.getCatchTypeClassName().equals("java/lang/RuntimeException")) { 
        for(int index = e.getHandlerIndex(); index < code.getInstrLength(); index++) { 
         JInstruction instr = code.getInstruction(index); 
         if(instr.getOpcode() == ATHROW) 
          break; 
         else if(instr instanceof ReturnInstruction) 
          break label; 
        } 
        removeStuff(code, ei--); 
       } 
      } 
    } 
} 

C#代碼。

foreach(JClass c in classes) { 
    foreach(JMethod m in c.getMethods()) { 
     JCode code = m.getCode(); 
     if(code == null) 
      continue; 

     for(int index = 0; index < code.getExceptionTable().Length; index++) { 
      bool continueELoop = false; 
      bool breakELoop = false; 
      JException e = code.getExceptionTable().get(index); 
      for(int index2 = e.getStartIndex(); index2 < e.getEndIndex(); index2++) { 
       if(code.getInstruction(index2).getOpcode() == JInstructions.NEW && ((NEW) code.getInstruction(index2)).getType().Equals("java/lang/RuntimeException")) { 
        continueELoop = true; 
        break; 
       } 
      } 
      if(continueELoop) continue; 

      if(e.getCatchTypeClassName().Equals("java/lang/RuntimeException")) { 
       for(int index = e.getHandlerIndex(); index < code.getInstrLength(); index++) { 
        JInstruction instr = code.getInstruction(index); 
        if (instr.getOpcode() == JInstructions.ATHROW) { 
         break; 
        } else if (isReturnInstruction(instr)) { 
         breakELoop = true; 
         break; 
        } 
       } 
       removeStuff(code, ei--); 
      } 
      if (breakELoop) break; 
     } 
    } 
} 

看Java版本,然後看着將要移植的C#版本時,你可以看到..乾淨的感覺消失。我是否犯了一些可以縮短代碼的錯誤?或更好看?謝謝您的幫助。

+3

也許我老了,但我會打入更多比一種方法。比你可以利用返回表達式作爲僞中斷標籤。 –

+0

'斷標籤'與GOTO有什麼不同? – Cameron

+0

它不是,但goto的看起來更糟,然後只使用bool條件。至少我這樣看到'continue

回答

3

我想,在C#中,你永遠不會寫擺在首位這種醜陋的代碼。

,這裏是你的代碼重構到多種方法和與虛構類層次結構使用LINQ:

IEnumerable<JCode> GetCodes(IEnumerable<JClass> classes) 
{ 
    return from @class in classes 
      from method in @class.Methods 
      where method.Code != null 
      select method.Code; 
} 

IEnumerable<Tuple<JCode, JException>> GetCandidates(IEnumerable<JCode> codes) 
{ 
    return from code in codes 
      from ex in code.ExceptionTable 
      where !code.Instructions 
         .Skip(ex.Start) 
         .Take(ex.End - ex.Start + 1) 
         .Any(i => i.OpCode == New && ...) 
      select Tuple.Create(code, ex); 
} 

然後

void RewriteMethods(IEnumerable<JClass> classes) 
{ 
    var codes = GetCodes(classes); 

    var candidates = GetCandidates(codes); 

    foreach (var candidate in candidates) 
    { 
     var code = candidate.Item1; 
     var ex = candidate.Item2; 

     var instructionsToRemove = code.Instructions 
             .Skip(ex.HandlerStart) 
             .TakeWhile(i => i.OpCode != Return) 
             .Where(i => i.OpCode == AThrow); 

     code.RemoveAll(instructionsToRemove); 
    } 
} 
+0

太過分了,要求有人來自java直接寫linq –

+1

你可能是對的。但是,如果你想編寫醜陋的Java代碼,爲什麼要切換到C#? – dtb

+0

哈哈絕對看起來更清潔..但你是對的Pinaktin Linq看起來外星人,有點像我的SQL:PI可能不會有自己編寫Linq代碼的能力,所以我爲什麼要複製/粘貼這個..我不會如果發現錯誤,不瞭解如何修改它。也許我可以使用RemoveAll刪除一些冗餘代碼。我更喜歡函數編碼。但是,呃這是最好的答案,我想我會標記它,它肯定會幫助很多google的。 – SSpoke

-1

和continue是一種快捷方式

我寧願使用的if/else結構來格式化這個更好,使它更清潔。你可以擺脫這兩種語言中的繼續語句。你可以通過在for循環中添加一個附加條件來做同樣的工作。這又是一個個人喜好。

例如

if(code == null) continue; 

if(code != null) 
{ 

} 
0

如果我們純粹談論語言規範,沒有什麼相當於 在C#中繼續並中斷。只有看起來像這樣的東西轉到哪個不是真正的替代品。我懷疑這樣的事情會被包含在未來的C#版本中,因爲Anders Hejlsberg似乎不喜歡任何可能混淆代碼一致性的東西。

沒有文件,指出有些功能沒有實現,所以我只能把你介紹給另一個回答這樣的問題上計算器:) C# equivalent to Java's continue <label>?