stepping through a collection object in a foreach loop

D

David C

This is very strange. Say I have code like this. I am simply looping
through a collection object in a foreach loop.

Course course = new Course();

foreach(Student s in course.Students)
{
Console.WriteLine(s.StudentID);
}

When I run the code without debugging, it runs fine. Then when I step
through the loop, I get this error.

An unhandled exception of type 'System.InvalidOperationException'
occurred in mscorlib.dll

Additional information: Collection was modified; enumeration operation
may not execute.


The implmentation of course.Students? Very straightforward.

public ArrayList Students
{
get
{
if (students == null)
students = new ArrayList();

for(int i=0; i<5; i++)
{
Student s = new Student();
s.StudentID = i;
students.Add(s);
}
return students;
}
}

I want Students to be refreshed every time it's called. Now if I do
this (see below), this code will make sure that the Students gets
populated only once. That is not what I want.

What is very strange is that I've been doing this the past 3 years.
Stepped through loops about a trillion types and my implmentation has
always been like the one above.

What I have is a fresh installation of .NET. This is just strange.

public ArrayList Students
{
get
{
if (students == null)
{
students = new ArrayList();

for(int i=0; i<5; i++)
{
Student s = new Student();
s.StudentID = i;
students.Add(s);
}
}
return students;
}
}
 
G

Guest

Hi David,
the reason for your error is that while you are looping throught the
Students arraylist i.e.
Course course = new Course();

foreach(Student s in course.Students)
{
Console.WriteLine(s.StudentID);
}

The Students array list was modified which is not allowed. Are you running
this code in a multithreaded environment. Something must have called
course.Students on the same instance of course while another thread was in
the foreach loop.

I would place a lock around the setting and getting of the students
arraylist to make sure it cannot be modified whilst you are looping through
it something like:

public ArrayList Students
{
get
{
if (students == null)
students = new ArrayList();

lock(students.SyncRoot)
{
for(int i=0; i<5; i++)
{
Student s = new Student();
s.StudentID = i;
students.Add(s);
}
}
return students;
}
}

and


Course course = new Course();

lock(course.Students.SyncRoot)
{
foreach(Student s in course.Students)
{
Console.WriteLine(s.StudentID);
}
}

Hope that helps
Mark R Dawson
http://www.markdawson.org
 
D

Daniel Jin

David said:
This is very strange. Say I have code like this. I am simply looping
through a collection object in a foreach loop.

Course course = new Course();

foreach(Student s in course.Students)
{
Console.WriteLine(s.StudentID);
}

When I run the code without debugging, it runs fine. Then when I step
through the loop, I get this error.

An unhandled exception of type 'System.InvalidOperationException'
occurred in mscorlib.dll

Additional information: Collection was modified; enumeration operation
may not execute.


The implmentation of course.Students? Very straightforward.

public ArrayList Students
{
get
{
if (students == null)
students = new ArrayList();

for(int i=0; i<5; i++)
{
Student s = new Student();
s.StudentID = i;
students.Add(s);
}
return students;
}
}

I want Students to be refreshed every time it's called. Now if I do
this (see below), this code will make sure that the Students gets
populated only once. That is not what I want.

you are not refreshing anything. every time the get accessor is
called, you add 5 more Student objects to it.

when the debugger is running, in order to display the information in
the debugger, it will invoke the get accessor and cause 5 more objects
to be added to the ArrayList, and foreach loop fails.
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,

You cannot modify the collection when you are iterating.

if you want to update the collection elements you would have to implement
the iterator yourself.


you could implement IEnumerator.Current like:

object IEnumerator.Current
{
get
{
//update the student
students[ i].Update(); //or whatever method you use
return students[ i++];
}
}




cheers,
 
S

SharpCoderMP

public ArrayList Studentsand also you shouldn't do things like this in a getter
 
D

David C

Thank you all for your replies.

I had a friend run the code with his install of VS.NET 2003, and can
step through this without a problem.

So looks like there is a problem with my instance of VS.NET 2003. I
wouldn't know how to began to address that.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top