首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在<label>中重写Java [继续<label>和中断<label>]?

如何在<label>中重写Java [继续<label>和中断<label>]?
EN

Stack Overflow用户
提问于 2011-07-20 02:36:03
回答 3查看 1.4K关注 0票数 0

在Java里它是这样写的。当我移植这个代码的时候..。意识到没有break <label>continue <label>这样的东西。

我知道这些命令没有包括在内,因为在使用goto命令时必须有一种更干净的方法。

但最后我用了..。下面的C#代码可以用更干净的方式重写吗?

Java代码

代码语言:javascript
复制
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#代码.

代码语言:javascript
复制
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#版本。干净的感觉消失了。我是不是犯了一些错误,使代码变短了?还是更好看?谢谢你的帮助。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-07-20 02:59:17

我想,在C#中,您一开始就不会编写这么难看的代码。

下面是重构成多个方法的代码,并将LINQ与虚构的类层次结构一起使用:

代码语言:javascript
复制
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);
}

然后

代码语言:javascript
复制
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);
    }
}
票数 3
EN

Stack Overflow用户

发布于 2011-07-20 03:35:28

如果我们纯粹是在谈论语言规范,那么在C#中没有什么等同于继续和中断。唯一看起来是这样的就是goto,它并不是一个真正的替代品。我怀疑将来的c#版本中会包含这样的东西,因为似乎不喜欢任何可能破坏代码一致性的东西。

没有文档说明某些功能没有实现,所以我只能向您介绍关于stackoverflow :) C# equivalent to Java's continue ?的问题的另一个答案

票数 0
EN

Stack Overflow用户

发布于 2011-07-20 02:54:09

中断和继续是一种捷径。

我更愿意使用If / Else构造来更好地格式化它并使其变得更干净。您可以在这两种语言中去掉can语句。通过在for循环中添加一个附加条件,也可以对中断执行相同的操作。同样,这也是个人偏好。

例如:

代码语言:javascript
复制
 if(code == null) continue;

代码语言:javascript
复制
if(code != null)
{

}
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6756383

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档