文件系统异常处理中使用goto语句是否属于合法编程用法?
关于C#中goto在重试场景的合法性问题
代码示例
save: try { s.Save(); } catch (Exception ex) when (ex is IOException or UnauthorizedAccessException) { FSErrorDialog fsError = new(ex, FSVerb.Access, new FileInfo(path), Button.Retry, Button.Ignore); if (fsError.ShowDialog().ClickedButton == Button.Retry) { goto save; } }
问题描述
这段代码里的Save()方法用于将对象保存到磁盘。当发生IOException或UnauthorizedAccessException这类外部异常时,会弹出对话框提示用户重试,避免未保存的数据丢失。
我知道可以用while(true)循环加break实现同样逻辑,但觉得用goto的写法可读性更强,还能少一层缩进。不过我对使用goto有点顾虑,想问问这种场景下用goto是不是合理的合法用法?
回答
这种场景下使用goto完全是合法且合理的用法。
在C#中,goto并非是需要完全规避的语法,官方也认可它在特定场景下的价值——比如这种需要直接回到操作起始点重试的控制流场景。它的优势在于避免了额外的循环嵌套缩进,让重试逻辑的跳转关系更直观。
对比while(true)的实现方式:
while(true) { try { s.Save(); break; } catch (Exception ex) when (ex is IOException or UnauthorizedAccessException) { FSErrorDialog fsError = new(ex, FSVerb.Access, new FileInfo(path), Button.Retry, Button.Ignore); if (fsError.ShowDialog().ClickedButton != Button.Retry) { break; } } }
可以明显看到goto版本少了一层循环缩进,逻辑跳转更直接:用户选择重试时,直接回到保存操作的起始点,无需在循环内部做额外的终止判断。
行业内的共识是,goto的风险在于滥用(比如跨多个代码块无规则跳转,导致控制流混乱),但在这种单一方向的重试跳转场景下,它的使用是被广泛接受的,甚至比嵌套循环的写法更清晰。
所以你完全不必有顾虑,这个写法是没问题的。
内容的提问来源于stack exchange,提问作者Scover
相关产品推荐
相关产品推荐

