[英]How to rewrite Java [continue <label> and break <label>] in C#?
在 Java 中是這樣寫的..當我移植這段代碼時......意識到沒有break <label>
和continue <label>
這樣的東西。
我知道這些命令不包括在內,因為在使用帶有命令的 goto 時必須有一種更簡潔的方法。
但我最終使用.. 下面的 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# 版本時,您會看到......干凈的感覺消失了。 我是否犯了一些可以使代碼更短的錯誤? 還是更好看? 謝謝您的幫助。
我想,在 C# 中,你一開始就不會寫出如此丑陋的代碼。
這是您的代碼重構為多種方法,並使用 LINQ 和虛構的 class 層次結構:
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);
}
}
如果我們純粹在談論語言規范,那么在 C# 中沒有什么可以等同於繼續和中斷。 唯一看起來像的東西是 goto ,它並不是真正的替代品。 我懷疑這樣的東西是否會包含在未來的 c# 版本中,因為 Anders Hejlsberg 似乎不喜歡任何會影響代碼一致性的東西。
沒有文檔說某些功能沒有實現,所以我只能參考stackoverflow上此類問題的另一個答案:) C# 相當於Java的 continue <label>?
Break 和 Continue 是一種捷徑
我寧願使用 If / Else 構造來更好地格式化它並使其更干凈。 您可以擺脫兩種語言中的 continue 語句。 您可以通過在 for 循環中添加一個附加條件來對 break 執行相同的操作。 這又是個人喜好。
例如
if(code == null) continue;
至
if(code != null)
{
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.