添加/删除2个阵列的元素时出现InvalidOperationException

时间:2015-09-07 18:07:31

标签: c#

作为学校项目的一部分,我正在创建一个程序,模拟学生进行测试,学生检查他的成绩,然后学生返回测试。我觉得好像我已经关闭了程序,但现在VisualBasic为我的foreach循环抛出一个InvalidOperationException,因为该集合已被修改。据我所知,我的程序正在工作(我有一个按预期运行的调试行)。

我在C#上比较新,所以如果我在任何地方离开基地,请告诉我。代码如下。

首先是错误

  

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

     

其他信息:收集已修改;枚举操作   可能无法执行。

代码(如果有人需要我的对象类,只需这样说)

//Stack and Queue calls
Queue submittedTest = new Queue();
Stack outForChecking = new Stack();
private void btnSubmitTest_Click(object sender, EventArgs e)
{
    //generates a random test score
    Random rdm = new Random();
    int testScore = rdm.Next(0, 100);
    string score = testScore.ToString();

    //assigns user input to a variable
    string name = txtName.Text;

    //Generate a new test that passes in 
    Test tests = new Test(name, score);

    //shows the user the name they just enetered
    label3.Text = String.Format("{0}", name);

    //adds submitted test to the queue, then displays that test in a list box
    submittedTest.Enqueue(tests);
    listSubTests.Items.Add(new Test(name, score));

    //Clears input box for next user input
    txtName.Clear();
}
private void btnFindTest_Click(object sender, EventArgs e)
{
    string tempName = txtName.Text;

    foreach (Test tests in submittedTest)
    {
        if(tests.Name == tempName)
        {
            //Remove correct test from submittedTest que
            submittedTest.Dequeue();

            //Add correct test to a new array, outForChecking
            outForChecking.Push(tests);

            //Tester to validate how many items are left in the submittedTest que
            Console.WriteLine("{0}", submittedTest.Count);
        }
    }
}

3 个答案:

答案 0 :(得分:1)

在C#中,您无法修改通过foreach循环进行迭代的集合。

此外,正如在注释中向上注意到的那样,Dequeue方法会删除队列的最后一项,而不是当前项(这可能会导致代码中出现逻辑错误)。考虑将submittedTest变量更改为实现IList<T>接口的任何内容(可能List<T>可能会很好)。

然后你可以像这样迭代它:

for (int i = submittedTest.Count-1; i>=0; i--)
{
    var tests = submittedTest[i];
    if(tests.Name == tempName)
    {
        //Remove correct test from submittedTest que
        submittedTest.Remove(tests);

        //Add correct test to a new array, outForChecking
        outForChecking.Push(tests);

        //Tester to validate how many items are left in the submittedTest que
        Console.WriteLine("{0}", submittedTest.Count);
    }
}

请注意,此示例在反向for循环中迭代集合。 This is needed to avoid OutOfRangeException when iterating over it.

答案 1 :(得分:0)

更改此

 foreach (Test tests in submittedTest)
{
    if(tests.Name == tempName)
    {
        //Remove correct test from submittedTest que
        submittedTest.Dequeue();

        //Add correct test to a new array, outForChecking
        outForChecking.Push(tests);

        //Tester to validate how many items are left in the submittedTest que
        Console.WriteLine("{0}", submittedTest.Count);
    }
}

for(int i = 0; i < submittedTest.Count - 1; i++)
{

if(submittedTest[i].Name == tempName)
    {
        //Remove correct test from submittedTest que
        submittedTest.Dequeue();

        //Add correct test to a new array, outForChecking
        outForChecking.Push(submittedTest[i]);

        //Tester to validate how many items are left in the submittedTest que
        Console.WriteLine("{0}", submittedTest.Count);
    }
}

答案 2 :(得分:0)

在这里,队列和堆栈似乎都不合适。你的收藏品应该都是这样的词典:

submittedTest = new Dictionary<string, Test>();
outForChecking = new Dictionary<string, Test>(); 

然后,而不是

submittedTest.Enqueue(tests);

你会写

submittedTest[tests.Name] = tests;

我假设&#34;姓名&#34;是&#34;对象类&#34;的公共财产。您的搜索点击方法如下所示:

private void btnFindTest_Click(object sender, EventArgs e)
{
    Test found = null;
    string name = txtName.Text;
    if (submittedTest.TryGetValue(name, out found))
    {
        submittedTest.Remove(name);
        outForChecking [name] = found;
        //Tester to validate how many items are left in the submittedTest que
        Console.WriteLine("{0}", submittedTest.Count);
    }
} 

您的提交例程应执行类似的检查。如果在outForChecking字典中找到了学生的测试,则应将其删除并放回到submittedTest字典中。