I have this code:
try
{
Console.WriteLine("Input number {0}", i + 1);
int number = ReadNumber(start, end);
}
catch (Exception ex)
{
if (ex is ArgumentException)
{
Console.WriteLine("The input number wasn't in the alowed range. Please try again.");
}
else if (ex is FormatException)
{
Console.WriteLine("The input isn't an integer number. Please try again.");
}
else
{
Console.WriteLine("An unknown error occured. Please try again.");
}
i--;
}
I am wondering if there is a better way to do this - catch all exceptions and handle them and then, if any exception was caught, I want to reduce i
by 1.
-
2\$\begingroup\$ you can use different catch blocks for different type of exceptions \$\endgroup\$Selman Genç– Selman Genç2014年09月04日 14:05:49 +00:00Commented Sep 4, 2014 at 14:05
-
\$\begingroup\$ I don't think you understood, I want to be able to catch all exceptions and handle them, BUT then have a code that is executed after all catch-es and only if one of them was entered. \$\endgroup\$frostblooded– frostblooded2014年09月04日 14:08:39 +00:00Commented Sep 4, 2014 at 14:08
-
\$\begingroup\$ So you want i-- to happen only if an exception is caught, or you want it to happen regardless? \$\endgroup\$eddie_cat– eddie_cat2014年09月04日 14:10:16 +00:00Commented Sep 4, 2014 at 14:10
-
\$\begingroup\$ Only if an exception was caught :) And it works the way I did it, but I was wondering if there was a better way to do it. If there is a special operator to do it or something like that. \$\endgroup\$frostblooded– frostblooded2014年09月04日 14:11:12 +00:00Commented Sep 4, 2014 at 14:11
-
\$\begingroup\$ This looks fine to me. \$\endgroup\$eddie_cat– eddie_cat2014年09月04日 14:13:35 +00:00Commented Sep 4, 2014 at 14:13
2 Answers 2
So I'm assuming that all of this code is in a for
loop, and that for
loop is incrementing i
as it's loop statement.
What you can do here is not unconditionally increment i
in each iteration of the loop, and instead only increment i
if you're able to read in the number successfully:
for (int i = 0; i < 10; )
{
try
{
Console.WriteLine("Input number {0}", i + 1);
int number = ReadNumber(start, end);
i++;
}
catch (ArgumentException)
{
Console.WriteLine("The input number wasn't in the alowed range. Please try again.");
}
catch (FormatException)
{
Console.WriteLine("The input isn't an integer number. Please try again.");
}
catch (Exception)
{
Console.WriteLine("An unknown error occured. Please try again.");
}
}
However, for this case I'd say that there's an option that's better still.
What you should really do is, rather than having a method try to get another value from the user and possibly failing and possibly succeeding and needing to be called again, create a method that keeps asking the user for a value until it gets a valid one. This logic is far easier to implement at that scope than it is to try to continually add more iterations to the loop.
Once you create a method that will always get a valid value, trying as hard as it needs to:
public static int ReadNumber(int start, int end, int iteration)
{
while (true)
{
Console.WriteLine("Input number {0}", iteration + 1);
int n;
if (!int.TryParse(Console.ReadLine(), out n))
Console.WriteLine("The input isn't an integer number. Please try again.");
else if (n < start || n > end)
Console.WriteLine("The input number wasn't in the alowed range. Please try again.");
else
return n;
}
}
(Also note the use of conditional checks to determine if the user input is valid, rather than using exceptions for non-exceptional control flow.)
Now our loop is dead easy:
for (int i = 0; i < 10; i++)
{
int number = ReadNumber(start, end, i);
}
-
\$\begingroup\$ Your answer makes a lot of sense and I like it. Thanks! \$\endgroup\$frostblooded– frostblooded2014年09月07日 10:59:16 +00:00Commented Sep 7, 2014 at 10:59
You could set a bool
indicating if an exception was caught. I see no superiority in this way, but it exists.
You might also consider catching these in seperate catch
statements:
var wasCaught = false;
try
{
Console.WriteLine("Input number {0}", i + 1);
int number = ReadNumber(start, end);
}
catch (Exception ex)
{
wasCaught = true;
if (ex is ArgumentException)
{
Console.WriteLine("The input number wasn't in the alowed range. Please try again.");
}
else if (ex is FormatException)
{
Console.WriteLine("The input isn't an integer number. Please try again.");
}
else
{
Console.WriteLine("An unknown error occured. Please try again.");
}
}
if (wasCaught)
{
i--;
}