[英]Can/Should I replace this GOTO statement in C#
using goto seems natural in here . 使用goto在这里看起来很自然 。
A project needs to read pdf file, a pdf file can be one of below. 一个项目需要阅读pdf文件,pdf文件可以是下面的一个。
A file can only be accessed with correct password, there is no way to know which password the file need upfront. 只能使用正确的密码访问文件,无法预先知道文件需要哪个密码。 we have to try all cases, (include no password).
我们必须尝试所有情况,(不包括密码)。 if none of above password works, throw exception.
如果以上密码均无效,则抛出异常。
PdfReader GetPdfReader(string filePath)
{
PdfReader r = null;
int Retries = 0;
start: try
{
switch (Retries)
{
case 0: r = new PdfReader(filePath); break;
case 1: r = new PdfReader(filePath, password1); break;
case 2: r = new PdfReader(filePath, password2); break;
case 3: r = new PdfReader(filePath, password3); break;
}
}
catch (BadPasswordException ex)
{
if (Retries == 3) throw ex;
Retries++;
goto start;
}
return r;
}
Embed try/catch is working but looks ugly, using goto seem natural. 嵌入式try / catch正在运行,但看起来很难看,使用goto看起来很自然。
Two questions: 两个问题:
Thanks 谢谢
Goto, just like nuclear power or bacon, is not inherently evil. Goto,就像核能或培根一样,本身并不是邪恶的。 It's a matter of what you do with it.
这是你用它做什么的问题。
The current code is fairly clearly structured. 目前的代码结构清晰。 Goto is not being used to create spaghetti code .
Goto不会被用来创建意大利面条代码 。
Having said that, I would still replace it with a while
loop. 话虽如此,我仍然会用
while
循环替换它。 Goto
can be a slippery slope. Goto
可以是一个滑坡。
bool passwordIsOK = false;
while (!passwordIsOK && Retries < 3)
{
// Existing code, without "goto start;". Set passwordIsOK = true when appropriate.
// See also @Sriram's comment about using "throw" rather than "throw ex".
}
I think you should replace the goto in this case as to me the issue is that your code and retries are clouding the intent. 我认为你应该在这种情况下替换goto,因为我的问题是你的代码和重试使意图蒙上阴影。 I personally would replace the code with something like this:
我个人会用这样的代码替换代码:
PdfReader GetPdfReader(string filePath)
{
PdfReader r = null;
string [] passwordsToTry = new string [] {null, password1, password2, password3};
foreach(string password in passwordsToTry)
{
try
{
r = (password == null) ?
new PdfReader(filePath)
: new PdfReader(filePath, password);
if (r != null)
break;
}
catch(BadPasswordException){ }
}
return r;
}
To me the code is clearer as it shows: 对我来说,代码更清晰,因为它显示:
The other thing is that your code with 3 passwords is slightly brittle if you had to deal with more or less passwords. 另一件事是,如果您不得不处理更多或更少的密码,那么带有3个密码的代码会稍微脆弱。 And I think using a variable like passwordsToTry fits nicely with the 'try' statement.
我认为使用像passwordsToTry这样的变量可以很好地适应'try'语句。
You can do a while(true)
with a break
: 你可以
break
while(true)
:
PdfReader GetPdfReader(string filePath)
{
PdfReader r = null;
int Retries = 0;
while(true)
{
try
{
switch (Retries)
{
case 0: r = new PdfReader(filePath); break;
case 1: r = new PdfReader(filePath, password1); break;
case 2: r = new PdfReader(filePath, password2); break;
case 3: r = new PdfReader(filePath, password3); break;
}
break;
}
catch (BadPasswordException ex)
{
if (Retries == 3) throw ex;
Retries++;
}
}
return r;
}
This avoids adding any extra variables. 这可以避免添加任何额外的变量。 This topic goes over pros/cons of
goto
. 本主题讨论了
goto
优点/缺点。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.