使用列表和for循环索引超出范围

时间:2018-05-22 09:19:43

标签: c# list indexoutofrangeexception

我在这里有这个循环,对于它应该创建的每个问题,它生成并格式化一个措辞问题'从一系列问题,如; ' {0} + {1}的总和是多少?'。然后,这个循环将其格式化,添加措辞问题和数组的答案。

// Use for loop to create the correct amount of questions
                for (int i = 0; i < Data.Questions.numQuestions; i++)
                {
                    Random rnd = new Random();
                    Data.Questions.Sum sum = new Data.Questions.Sum();

                // Create part one and part two of the question using random numbers
                // ex. 3 + 5
                // 3 = partOne, 5 = partTwo
                int partOne = rnd.Next(Data.Questions.Sum.min, Data.Questions.Sum.max);
                int partTwo = rnd.Next(Data.Questions.Sum.min, Data.Questions.Sum.max);

                // Randomly select one of the word questions
                string fullQuestion = Data.Questions.Sum.wordedQuestions[rnd.Next(0, Data.Questions.Sum.wordedQuestions.Length)];

                // Format the string with the generated numbers
                fullQuestion = string.Format(fullQuestion, partOne, partTwo);

                // Set out-of-class variables to be displayed to the user
                Data.Questions.Sum.questions[i] = fullQuestion;
                Data.Questions.Sum.answers[i] = partOne + partTwo;
            }

Data.Questions.Sum.questionsData.Questions.Sum.answers都是List<string>&{39}和List<int>

然而,当这个循环运行时,i = 0,我被抛出;

  

System.ArgumentOutOfRangeException:&#39;索引超出范围。一定是   非负面且小于集合的大小。参数名称:   索引&#39;

有谁知道我做错了什么?据我所知,列表是动态的,我已经这样定义了;

// Arrays containing all questions and answers
                // used to display questions and check answers
                public static List<string> questions = new List<string>();
                public static List<int> answers = new List<int>();

另外,为了澄清,我想要使用.Add(),因为我有一个设置面板,当你点击apply时,重新运行这个循环以便问题是最新的到当前的设置。我需要循环来覆盖以前的值。

编辑: 使用数组时,这里有更好的选择,我得到了;

  

System.IndexOutOfRangeException:&#39;索引超出了数组的范围。&#39;

在分配Data.Questions.Sum.answers[i]之后,在分配数组后如此; public static int[] answers {};

3 个答案:

答案 0 :(得分:0)

如果您不能在此列表中.Add() - 请在此处创建此列表和.Add()的副本。列表对于这类事情有特殊之处:new List<T>(IEnumerable<T>)

答案 1 :(得分:0)

如果您需要动态扩展集合,但您还需要多次迭代它,那么您需要检查它是否足够大以插入或只是更新。

您可以使用此扩展方法执行此操作...

public static class ListExtentions
{
    public static void AddOrUpdate<T>(this List<T> that, int index, T value)
    {
        if (that.Count > index)
        {
            that[index] = value;
        }
        else
        {
            that.Add(value);
        }
    }
}

......然后可以这样调用......

list.AddOrUpdate(index, value);

...但是,如果您知道自己将要开始提出多少问题,那么您可以让自己更轻松。

如果您的用户界面发生变化时问题的数量发生了变化,那么您还必须处理这个问题,并对该集合进行扩展向下,以确保删除旧元素,如果您只是更简单的话每次需要重新生成问题/答案时,重新实例化集合。

答案 2 :(得分:0)

这很可能是导致您出现问题的原因(我已在您没有回复的评论中要求澄清)。

仍然把它作为答案,因为它是潜在的错误点,你需要解决这个问题。

正如您所提到的,您在i=0上面临此例外。很有可能这种情况每次都不是特定情况。

如果Data.Questions.Sum.questions为空,那么Data.Questions.Sum.questions[i] = fullQuestion;肯定会抛出此异常。同样适用于Data.Questions.Sum.answers

在这种情况下,您必须使用.Add()插入列表。

所以你的代码应该是,

if (Data.Questions.Sum.questions.Count > i)
    Data.Questions.Sum.questions[i] = fullQuestion;
else
    Data.Questions.Sum.questions.Add(fullQuestion);

但如果它们不是空的,那么它一定不是这个例外的原因。

我在代码中注意到的另一件事是Data.Questions.Sum.wordedQuestions

即使你有有效的列表(这里是Data.Questions.Sum.wordedQuestions) - 因为你有Length道具,它必须是数组而不是列表。

如果它是空的,那么这样做

string fullQuestion = Data.Questions.Sum.wordedQuestions[rnd.Next(0, Data.Questions.Sum.wordedQuestions.Length)];

这一行肯定会抛出

  

mscorlib.dll中出现未处理的“System.ArgumentOutOfRangeException”类型异常

因为你试图从中得到第0个索引的数据。

因此,在从列表或数组中获取数据之前,首先需要检查它是否具有数据init,并且它确实具有您要求的索引。

类似

string fullQuestion = string.Empty;

if (Data.Questions.Sum.wordedQuestions != null &&
    Data.Questions.Sum.wordedQuestions.Length > 0)
{
    //here the way you are creating random number, 
    // you are assured about index is present in array.
    int indexForWordedQuestion = rnd.Next(0, Data.Questions.Sum.wordedQuestions.Length);
    fullQuestion = Data.Questions.Sum.wordedQuestions[indexForWordedQuestion];
}