我得到一个System.IndexOutOfRangeException

时间:2018-11-29 18:15:16

标签: c# switch-statement try-catch

我当前的代码有问题。我正在像其他许多人一样从事一个项目,即著名的SodaCrate项目。 我不想要任何代码解决方案,但我想知道为什么我无法使用“ System.IndexOutOfRangeException”解决问题。 当我尝试在板条箱中添加超过24瓶时出现此错误(我对瑞典的评论表示歉意)。

这是我的代码:

public void add_soda()
{

    Console.WriteLine("\"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\"");
    Console.WriteLine("|     Choose your beverage!        |");
    Console.WriteLine("|                                  |"); // Välkomnar användaren
    Console.WriteLine("|[1] Pepsi , Soda, 11kr            |");
    Console.WriteLine("|[2] Coca-Cola , Soda, 12kr        |");
    Console.WriteLine("|[3] Coors Light , Beer, 18kr      |");
    Console.WriteLine("|[4] Fiji, Water , 13kr            |");
    Console.WriteLine("|[5] Nocco , Energy drink , 22kr   |");
    Console.WriteLine("|[6] Redbull , Energy drink , 25kr |");
    Console.WriteLine("|                                  |");
    Console.WriteLine("\"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\"");

    //Console.WriteLine("[7] Randomize");                       <---------- Fixa

    int temp = 0;

    while (!int.TryParse(Console.ReadLine(), out temp) || !(temp < 7 && temp > 0)) // Detta är en failsafe, ifall väljaren väljer något som är över 7 eller under 1 kommer följande kod att skrivas ut.
    {
        // Console.ForegroundColor = ConsoleColor.Red;
        Console.WriteLine("Invalid input, please try again.");
        // Console.ResetColor();
    }   

    switch (temp) // Denna switch statementen kommer låta oss lägga till flaskor i vår crate
    {
        case 1: //Om anändaren skriver in ett tal mellan 1 och 6, kommer följade cases att skriva ut deras WriteLines.
            Console.WriteLine(">>> You choose Pepsi <<<");
            myCrate[numberOfBottles] = new Bottle("Pepsi", "Soda", 11); // Här skapas en läsk med namnet Pepsi som kostar 11kr.
            numberOfBottles++; // Denna funktion gör så att en läsk läggs in i craten varje gång den skapas.
            break;
        case 2:
            Console.WriteLine(">>> You choose Coca-Cola <<<");
            myCrate[numberOfBottles] = new Bottle("Coca-Cola", "Soda", 12);
            numberOfBottles++;
            break;
        case 3:
            Console.WriteLine(">>> You choose Coors Light <<<");
            myCrate[numberOfBottles] = new Bottle("Coors Light", "Beer", 18);
            numberOfBottles++;
            break;
        case 4:
            Console.WriteLine(">>> You choose Fiji <<<");
            myCrate[numberOfBottles] = new Bottle("Fiji", "Water", 13);
            numberOfBottles++;
            break;
        case 5:
            Console.WriteLine(">>> You choose Nocco <<<");
            myCrate[numberOfBottles] = new Bottle("Nocco", "Energydrink", 22);
            numberOfBottles++;
            break;
        case 6:
            Console.WriteLine(">>> You choose Redbull <<<");
            myCrate[numberOfBottles] = new Bottle("Redbull", "Energydrink", 25);
            numberOfBottles++;
            break;
        default:
            //Console.ForegroundColor = ConsoleColor.Red;         // <<<<<-----------------   FIXA
            Console.WriteLine("Invalid choice!");
           // Console.ResetColor;
            break;
    }
    try
    {
        if(numberOfBottles >= 25)
        {   
            Console.WriteLine("The crate is currently full!");
        }
    }
    catch (IndexOutOfRangeException e)
    {
        Console.WriteLine(e.Message);
        throw new ArgumentOutOfRangeException("index paramater is out of range", e);
    }
}

有人可以给我一个想法或提示,为什么会引发异常? 我也尝试过if-else语句,但目前我很困惑。

2 个答案:

答案 0 :(得分:2)

您发生的问题是由于您尝试访问Bottle[]中不存在的一部分而引起的。由于已实例化数组具有一定的长度,因此不能超出该长度。最初(并且始终),在尝试访问它之前,应对照数组的Length属性检查要使用的索引。假设我们在整个示例中都有一个int[],并且最初给它的Length3

int[] someNumbers = new int[3];

在上述情况下,我们创建了一个新的int数组,其中分配了3个内存插槽。如果我们尝试使用硬编码的数字访问它,问题将变得非常明显:

someNumbers[0] = 1;
someNumbers[1] = 2;
someNumbers[2] = 3;
someNumbers[3] = 4; // Blows up here.

3的第四个索引不起作用的原因是,C#中的集合使用从零开始的索引访问;这意味着访问从零开始,然后从那里爬升。因此,从技术上讲,元素只是您认为它们所处位置的一个空格(如果您习惯于从一个开始的传统数字系统)。

如果采用相同的主体并改为使用变量访问数组,则将发生相同的事情,但它并不那么明显。我假设您知道++运算符对此的作用。

int index = 0;
int[] someNumbers = new int[3];
someNumbers[index++] = 1; // index = 0
someNumbers[index++] = 2; // index = 1
someNumbers[index++] = 3; // index = 2
someNumbers[index++] = 4; // index = 3 :: Blows up here.

由于完全相同的原因,它在3的第四个索引上爆炸了。解决此问题的方法是在访问之前检查索引:

if (index < someNumbers.Length)
    someNumbers[index++] = 1;

该代码之所以有效,是因为只有在索引位于数组范围内时,赋值才会执行。


调整数组大小

现在,在其他语言中,有很多方法可以很容易地调整数组的大小。但是C#不允许我们这样做。对我们来说是个好新奇,有个解决方法。再次,我将使用int[]进行演示。

假设我们创建的初始数组的长度为3:

int[] someNumbers = new int[3];

在路上的某个地方,出于某种原因,我们决定需要3个以上的数字;好吧,我们现在需要更大的阵列。为此(效率非常低下),您可以创建一个更大的新数组,然后添加所有旧值:

int[] newNumberArray = new int[someNumbers.Length + 10];
for (int i = 0; i < someNumbers.Length; i++)
    newNumberArray[i] = someNumbers[i];

上面的代码创建了一个更大的数组,并将所有旧值放入其中。请记住,这是一种非常低效的方法,我强烈建议改用List<T>或类似的对象。

答案 1 :(得分:-1)

我认为问题是,您在数组的myCrate []上使用了索引运算符,其中没有足够的空间。

如果您知道阵列中将有7个项目,请为其创建足够的位置。此代码应如下所示:

-B

现在,您可以在该数组上使用0到6的索引运算符