I'm following an old YouTube guide for C# learning and I'm stuck on one of the challenges for error handling.
class Program
{
static Board myBoard = new Board(8);
public static Cell setCurrentCell()
{
int currentRow, currentColumn;
// get x and y coordinates from the user. return a cell location
Console.Write("Enter a current row number: ");
while (true)
{
try
{
currentRow = int.Parse(Console.ReadLine());
break;
}
catch (FormatException)
{
Console.Write("Input has to be a number, try again:");
}
catch (IndexOutOfRangeException)
{
Console.WriteLine("Input was out of range, try a number between 0 and 8.");
Console.Write("Please try again: ");
}
}
Console.Write("Enter the current column number: ");
while (true)
{
try
{
currentColumn = int.Parse(Console.ReadLine());
break;
}
catch (FormatException)
{
Console.Write("Input has to be a number, try again:");
}
catch (IndexOutOfRangeException)
{
Console.WriteLine("Input was out of range, try a number between 0 and 8.");
Console.Write("Please try again: ");
}
}
}
return myBoard.theGrid[currentRow, currentColumn];
}
}
I'm trying to catch an error if user enters a number out of bounds but the catch just skips over it and then throws the error anyways. what am I doing wrong here?
CodePudding user response:
Following Int32.Parse
method documentation – exception type IndexOutOfRangeException
is not handled here.
If you want to check that value is less than Int32
min value or greater than Int32
max value, you should catch OverflowException
.
CodePudding user response:
IndexOutOfRangeException
is throw by an attempt to access an indexable collection (arrays, List<T>
, anything that implements IList<T>
, etc.) using an invalid index - less than 0 or greater than or equal to the collection size.
Here's the first try
block in your code:
try
{
currentRow = int.Parse(Console.ReadLine());
break;
}
Nothing in that block is attempting to index a collection, so we wouldn't expect IndexOutOfRangeException
to be thrown. In fact there are only two things in there that can throw an exception at all (int.Parse
and Console.ReadLine
), neither of which can throw IndexOutOfRangeException
under any circumstances.
There's only one line in your code that performs an indexing operation on a collection and that's the final return
statement... which is not contained in a try...catch
statement.
What you're trying to achieve is to range-check the entered values. There are a couple of ways to do this, but if you insist on using exceptions (which I wouldn't do, but you're learning I guess) then you can check the inputs by attempting to index the board's theGrid
array after the parse in each try
block like this:
try
{
currentRow = int.Parse(Console.ReadLine());
var test = myBoard.theGrid[currentRow, 0];
break;
}
And for currentColumn
:
try
{
currentColumn = int.Parse(Console.ReadLine());
var test = myBoard.theGrid[0, currentColumn];
break;
}
If the entered value (currentRow
or currentColumn
) is out of bounds then this will throw the IndexOutOfRangeException
as expected. (The 0
in the other index is guaranteed to not throw unless the row/column count is 0.)