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.

\$\endgroup\$
  • 2
    \$\begingroup\$ you can use different catch blocks for different type of exceptions \$\endgroup\$ – Selman Genç Sep 4 '14 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 Sep 4 '14 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 Sep 4 '14 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 Sep 4 '14 at 14:11
  • \$\begingroup\$ This looks fine to me. \$\endgroup\$ – eddie_cat Sep 4 '14 at 14:13
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);
}
\$\endgroup\$
  • \$\begingroup\$ Your answer makes a lot of sense and I like it. Thanks! \$\endgroup\$ – frostblooded Sep 7 '14 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--;
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.