如何在C#中重写Java[继续<;标签>;和中断<;标签>;]?

如何在C#中重写Java[继续<;标签>;和中断<;标签>;]?,c#,java,label,break,continue,C#,Java,Label,Break,Continue,在Java中,它是这样写的。。当我移植这段代码时。。。认识到世上没有 中断和继续 我知道这些命令没有包括在内,因为在使用goto命令时,必须有一种更干净的方法 但我最终还是用了。。下面的C代码有没有更干净的重写方法 Java代码 for(JClass c : classes) { for(JMethod m : c.getMethods()) { JCode code = m.getCode(); if(code == null)

在Java中,它是这样写的。。当我移植这段代码时。。。认识到世上没有
中断
继续

我知道这些命令没有包括在内,因为在使用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--);
                }
            }
    }
}
for(JClass c:类){
对于(JMethod m:c.getMethods()){
JCode code=m.getCode();
如果(代码==null)
继续;
标签:for(int index=0;index
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;
        }
    }
}
foreach(类中的JClass c){
foreach(c.getMethods()中的JMethod m){
JCode code=m.getCode();
如果(代码==null)
继续;
for(int index=0;index

您可以在查看Java版本然后再查看移植的C#版本时看到。。干净的感觉消失了。我是否犯了一些可以缩短代码的错误?还是好看一点?谢谢你的帮助。

中断和继续是一种快捷方式

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

e、 g

我想,在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);
}
IEnumerable GetCodes(IEnumerable类)
{
在类中从@class返回
@class.Methods中的from方法
where method.Code!=null
选择方法。代码;
}
IEnumerable(IEnumerable代码)
{
从代码中的代码返回
从代码中的ex.ExceptionTable
哪里!代码。指令
.跳过(例如开始)
.采取(例如结束-例如开始+1)
.Any(i=>i.OpCode==New&&…)
选择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);
    }
}
void重写方法(IEnumerable类)
{
var代码=获取代码(类别);
var候选者=获取候选者(代码);
foreach(候选人中的var候选人)
{
var代码=候选者.Item1;
var ex=候选项目2;
var指令存储移动=代码。指令
.跳过(例如HandlerStart)
.TakeWhile(i=>i.OpCode!=返回)
。其中(i=>i.OpCode==AThrow);
代码.RemoveAll(指令存储移动);
}
}

如果我们纯粹谈论语言规范,那么没有什么可以与 继续并打断C#。唯一看起来像goto的东西不是真正的替代品。我怀疑这样的东西是否会被包括在未来的c#版本中,因为Anders Hejlsberg似乎不喜欢任何会破坏代码一致性的东西

没有任何文档表明某些功能未实现,因此我只能让您参考有关stackoverflow的此类问题的另一个答案:)

也许我已经老了,但我会尝试多种方法。使用返回表达式作为伪break-to-label时,您可以利用它。
break-label
与GOTO有何不同?这不是但是GOTO看起来比使用bool条件更糟糕。。至少像这样,我可以看到
continue
break
之间的相似性。除非有办法使用goto执行
继续标签
,否则我将更改它。@Cameron:goto允许任意跳转,
中断标签
只能跳转到
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);
    }
}