【问题标题】:Out of bounds exception whilst using arrays使用数组时出现越界异常
【发布时间】:2016-04-16 18:58:30
【问题描述】:

我有一个文本框数组,它们根据用户输入的内容动态变化。这些文本框包含一个代表作业分数的数字。这些分数链接到一个模块对象。所以如果用户有3个模块;第一和第二模块2个作业,第三个模块3个作业;那么总共将创建 7 个文本框供用户输入他们所有的分配标记。

我要做的是创建一个 keyup 事件处理程序,在该处理程序中它获取用户输入的数字,然后动态调用一个方法来显示模块的平均值。这就是我到目前为止所拥有的。每当用户输入字符时,都会调用以下方法:

public void calculateLevel4Modules(int counter) {
        //iterate through modules
        //iterate through assignts in that module
        //whilst iterating, check tb and set userscore
        //after iterating, update overall label with regards to modulecounter
        //int assignmentCounter = 0;
        //Console.WriteLine("in If statement.. " + counter);

        for (int moduleCounter = 0; moduleCounter < requiredLevelList().Count; moduleCounter++)
        {
            int totalNumberOfAssignmentsInCurrentModule = requiredLevelList().ElementAt(moduleCounter).Assignments.Count;
            Console.WriteLine("total number of assignmetns:  " + totalNumberOfAssignmentsInCurrentModule);
            assignmentCounter = assignmentCounter + totalNumberOfAssignmentsInCurrentModule;
            Console.WriteLine("assignment counter: " + totalNumberOfAssignmentsInCurrentModule);
            if (counter < assignmentCounter)
            {
                Console.WriteLine("in If statement.. " + userMarksTBLvl4[moduleCounter].Text);
                try
                {
                    int userMark = int.Parse(userMarksTBLvl4[counter].Text);
                    requiredLevelList().ElementAt(moduleCounter).Assignments.ElementAt(counter).UsersScore = userMark;
                    double modAvg = requiredLevelList().ElementAt(moduleCounter).getModuleScoreOverall();
                    moduleOverallLvl4[moduleCounter].Text = modAvg.ToString();
                    break;
                }
                catch (FormatException) { break; }

            }
            else { }
        }

如果用户有一个模块,它可以正常工作,但如果用户有两个或更多,那么我会在以下行中收到错误: requiredLevelList().ElementAt(moduleCounter).Assignments.ElementAt(counter).UsersScore = userMark;

我遇到了越界异常。我知道为什么;这是因为计数器基本上是输入的文本框的#,但我使用计数器,我正在访问不在分配列表中的东西。这是问题发生时的示例:

用户有 2 个模块。在每个模块中有 2 个作业,因此创建了 4 个文本框,它们的索引范围为 0 - 3。如果用户想在第二个模块上输入他们的第一个作业的分数,它基本上是在尝试写入第三个索引然后该元素崩溃,因为该模块仅包含 2 个分配。

【问题讨论】:

    标签: c# arrays winforms


    【解决方案1】:

    您的代码中有一些奇怪的东西让人难以回答。首先,您发布的代码无法编译,因此我们无法对其进行测试。

    你多次使用如下代码:

    requiredLevelList().ElementAt(moduleCounter)
    

    我假设requiredLevelList 是一种返回事物列表的方法。没有理由假设 requiredLevelList 每次调用它时都会返回相同的列表,甚至是具有相同数量元素的列表。也许在您的特定情况下确实如此,但这是一件危险的事情。您应该使用如下构造:

    foreach (var module in requiredLevelList())
    {
        int totalNumberOfAssignmentsInCurrentModule = module.Assignments.Count;
        ...
    
        module.Assignments.ElementAt(counter).UsersScore = userMark;
        ...
    }
    

    这样的代码:

    Console.WriteLine("total number of assignmetns:  " + totalNumberOfAssignmentsInCurrentModule);
    

    是在崩溃后尝试调试的症状。这是极其低效的。学习如何使用调试器;在你知道如何做到这一点之前,你不会成为一名高效的程序员。

    requiredLevelList().ElementAt(moduleCounter).Assignments.ElementAt(counter).UsersScore = userMark;
    

    您可能会在此处遇到越界异常,因为counterAssignments 的索引之外。由于您从未初始化或更改counter,因此我无法知道它是什么或应该是什么。调试器会告诉你这一点,使用一个。

    输入但我使用计数器输入的文本框的 #,我正在访问不在分配列表中的内容。

    好的,如果您正在输入“不在作业列表中”的内容,那么您必须对此进行测试并决定要做什么。也许是这样的:

    if (counter >= 0 && counter < module.Assignments.Count)
        module.Assignments.ElementAt(counter).UsersScore = userMark;
    else
        throw new Exception("I really have no idea what you want to do here.");
    

    这看起来也不对:

    moduleOverallLvl4[moduleCounter].Text = modAvg.ToString();
    

    您永远不会告诉我们moduleOverallLvl4 是什么,但在这里您假设它的大小与requiredLevelList() 返回的大小相同。也许他们在这种特殊情况下,但这是一个危险的假设。如果这些值相关,moduleOverallLvl4 应该包含在实现requiredLevelList 的任何类中,并且您应该有一个方法将getModuleScoreOverall() 分配给moduleOverallLvl4 的正确元素。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多