Click to See Complete Forum and Search --> : foreach loop problem.


dovobet
February 21st, 2010, 12:42 PM
Im havign an odd problem where a foreach loop that is supposed to delete all records only deletes half of the records.

foreach (Microsoft.Office.Interop.Outlook._ContactItem item in folder.Items)
{
item.Delete();
MessageBox.Show("contact gone");
}

the folder.Items is a MAPfolder ive created in outlook that has contacts inside it.

The loop will only delete half of the contacts from the folder. If I run the method twice, it then removes allof them. Why is this happening?

memeloo
February 21st, 2010, 01:17 PM
any exceptions are thrown?

dovobet
February 21st, 2010, 05:17 PM
any exceptions are thrown?

Nope nothing, all it does is do half of the collection. Then next time the method is ran. It will do half again.

rliq
February 21st, 2010, 05:34 PM
You are not allowed to modify the variable being used as the iterator in foreach loop. In your case the iterator is 'item' and you are deleting it in the loop.

Try:

for (Int32 i = 0; i < folder.Items.Count; i++)
folder.Items[i].Delete();


I guessed at 'Count', it may be 'Length' or some other property that gives the size of the collection.

There may even be a Clear() method, which may delete all of the items in the collection in one go.

Arjay
February 21st, 2010, 05:36 PM
You can't delete items while iterating through a collection.

Generally you solve this problem by identifying the items you wish to delete, copy them to a temp collection, iterate through the temp collection and delete each item in the original collection.

rliq
February 21st, 2010, 06:27 PM
If you are able to use LINQ on the collection, I believe you can delete them too.

dovobet
February 21st, 2010, 08:28 PM
You are not allowed to modify the variable being used as the iterator in foreach loop. In your case the iterator is 'item' and you are deleting it in the loop.

Try:

for (Int32 i = 0; i < folder.Items.Count; i++)
folder.Items[i].Delete();


I guessed at 'Count', it may be 'Length' or some other property that gives the size of the collection.

There may even be a Clear() method, which may delete all of the items in the collection in one go.

I had tried that however there is no Delete() method that can be invoked on the item in the collection. Neither is there a clear() method. There is a remove method but this does not seem to do anything either. I used the line below

cfolder.Items.Remove(i);

Arjay - Im not sure i understand how that will work. Wont it mean i am iterating through the collection i will delete anyway?

rliq
February 21st, 2010, 08:51 PM
dovobet,

In your example, you were calling the Delete() member, so I assumed that there was one?

Maybe you need:

for (Int32 i = 0; i < folder.Items.Count; i++)
{
Microsoft.Office.Interop.Outlook._ContactItem contactItem = folder.Items[i] as Microsoft.Office.Interop.Outlook._ContactItem contactItem;
contactItem.Delete();
}

I assume there is no "folder.Items.Clear()" member?

JonnyPoet
February 23rd, 2010, 04:42 PM
I had tried that however there is no Delete() method that can be invoked on the item in the collection. Neither is there a clear() method. There is a remove method but this does not seem to do anything either. I used the line below

cfolder.Items.Remove(i);

Arjay - Im not sure i understand how that will work. Wont it mean i am iterating through the collection i will delete anyway?During trying to delete items I would always suggest to go through the list from the end to the beginning. This makes sure the index of the items to delete will not be changed while deleting the items.
The remove method should work then.

foamy
February 24th, 2010, 04:33 AM
During trying to delete items I would always suggest to go through the list from the end to the beginning. This makes sure the index of the items to delete will not be changed while deleting the items.
The remove method should work then.

I was just about to say that :)

BigEd781
February 24th, 2010, 12:31 PM
Arjay - Im not sure i understand how that will work. Wont it mean i am iterating through the collection i will delete anyway?

But you are not using an iterator as you are with a foreach loop. Also, as long as the Delete() method does not modify the collection (but rather, the object itself) your foreach loop would be fine.

JonnyPoet
February 25th, 2010, 07:53 AM
But you are not using an iterator as you are with a foreach loop. Also, as long as the Delete() method does not modify the collection (but rather, the object itself) your foreach loop would be fine.But he simple wants to modify the collection so he cannot iterate but should dofor (Int32 i = folder.Items.Count-1;i>= 0; i--)
{

cfolder.Items.Remove(i);

}Simple moving from the last to the first item and deleting (= removing from collection) them, Thats all.:D

dovobet
February 27th, 2010, 09:16 AM
But he simple wants to modify the collection so he cannot iterate but should dofor (Int32 i = folder.Items.Count-1;i>= 0; i--)
{

cfolder.Items.Remove(i);

}Simple moving from the last to the first item and deleting (= removing from collection) them, Thats all.:D

That was the problem. I had to start frm the end and work upwards through the collection. Weird c#. Thank you for the help guys:)

JonnyPoet
February 27th, 2010, 09:51 AM
That was the problem. I had to start frm the end and work upwards through the collection. Weird c#. Thank you for the help guys:)This is not only a C# problem. Its more a problem of collections and their indexes.
If you have an indexed collection you normally dont want to have a missing index is the list isn't it? So if someone removes an Item all the items after that one are getting a new index. And thats the reason why you cannot
a) remove items by use of an iterator
b) If you want to remove items you have to go from the end to the first one, standardway- always.
There is only one exception: If you want to remove all of them remove always the first one and count the remaining items in the collection. Do that as long as the items Count are more then zero