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