3
\$\begingroup\$

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.

Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Sep 4, 2014 at 14:04
\$\endgroup\$
6
  • 2
    \$\begingroup\$ you can use different catch blocks for different type of exceptions \$\endgroup\$ Commented 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\$ Commented 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\$ Commented 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\$ Commented Sep 4, 2014 at 14:11
  • \$\begingroup\$ This looks fine to me. \$\endgroup\$ Commented Sep 4, 2014 at 14:13

2 Answers 2

3
\$\begingroup\$

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);
}
answered Sep 5, 2014 at 17:38
\$\endgroup\$
1
  • \$\begingroup\$ Your answer makes a lot of sense and I like it. Thanks! \$\endgroup\$ Commented Sep 7, 2014 at 10:59
2
\$\begingroup\$

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--;
}
answered Sep 4, 2014 at 14:25
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.