簡體   English   中英

如何在 C# 中重寫 Java [繼續<label>和中斷</label><label>]?</label>

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM