作为学校项目的一部分,我正在创建一个程序,模拟学生进行测试,学生检查他的成绩,然后学生返回测试。我觉得好像我已经关闭了程序,但现在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);
}
}
}
答案 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字典中。