Как переписать Java [продолжить <label>и разбить <label>] в C #? - PullRequest
0 голосов
/ 20 июля 2011

В 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 #.чистое чувство уходит.Я сделал несколько ошибок, которые могут сделать код короче?или лучше смотреть?спасибо за помощь.

Ответы [ 3 ]

3 голосов
/ 20 июля 2011

Полагаю, в 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 голосов
/ 20 июля 2011

Если мы просто говорим о спецификации языка, в C # нет ничего эквивалентного продолжению и разрыву.Единственное, что выглядит так, это goto, который на самом деле не является заменой.Я сомневаюсь, что такая вещь будет включена в будущие версии c #, так как Андерсу Хейлсбергу, похоже, не нравится все, что может испортить целостность кода.

Нет документа, в котором говорится, что некоторые функции не реализованы, поэтому я могу только отослать васна другой ответ на такой вопрос по stackoverflow :) C # эквивалентно продолжению Java

0 голосов
/ 20 июля 2011

Break и Continue являются разновидностями ярлыков

Я бы лучше использовал конструкцию If / Else, чтобы лучше отформатировать это и сделать его чище. Вы можете избавиться от операторов продолжения в обоих языках. Вы можете сделать то же самое для перерыва, добавив дополнительное условие в свои циклы for. Опять же, это личное предпочтение.

например.

 if(code == null) continue;

до

if(code != null)
{

}
...