In the code GetStat(), you added checks for areas which have errors due to programmer mistakes and when in production should never occur. Because of this, I believe, it is the correct time to use exceptions, instead of boundary checks. So the code should read:
public float GetStat(Stat stat, CharacterClass characterClass, int level)
{
try
{
BuildLookupTable();
return lookupTable[characterClass][stat][level-1];
}
catch (Exception) // should never get here
{
return 0;
}
}
I would also suggest logging the error, so that it can be found quicker.