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;
}
}
The Save()
method saves the object to the disk.
If an exogenous exception occurs, the user is prompted to retry the operation to avoid loosing unsaved data.
I know I could use a while (true)
loop with break statements but I think the goto approach is more readable. It also saves an indentation level.
I am scared of using goto.
Is this a legitimate use of goto statements?
CodePudding user response:
I would suggest declaring a boolean to track if you should retry. That way you can use a do/while loop:
bool shouldRetry;
do
{
try
{
s.Save();
shouldRetry = false;
}
catch (Exception ex) when (ex is IOException or UnauthorizedAccessException)
{
FSErrorDialog fsError = new(ex, FSVerb.Access, new FileInfo(AppDirectory.Scripts.Join(s.FilePath)), Button.Retry, Button.Ignore);
shouldRetry = fsError.ShowDialog().ClickedButton == Button.Retry;
}
}
while (shouldRetry);
To address the "more readable" aspect that you mentioned in the question, I think this is more readable for 2 reasons:
- We're using something that exists explicitly as a loop, so it's clear from the beginning that looping is possible. You don't need to find the
goto
to work out that it loops. - The variable name
shouldRetry
makes it abundantly clear why we are looping: because we need to retry.
CodePudding user response:
I suggest infinite loop; we loop until either we have no exception or when we decide to stop our attempts:
while (true) {
try {
s.Save();
break; // No more looping (success)
}
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; // No more looping (no more tries)
}
}