Removing Items programmatically - using foreach

  • Thread starter Thread starter Filippo P.
  • Start date Start date
F

Filippo P.

Hi there,
I have a menu (Collection) that needs to be trimmed based on security access
of the
logged user.


protected void AdjustMenuBasedOnUserSecurity(Items ItemsList)
{
foreach (Item i in ItemsList)
{
if (i.Items.Count > 0)
AdjustMenuBasedOnUserSecurity(i.Items);

if (i.Tag == null)
continue;

if (this.LoggedUser.HasPermission(Convert.ToInt32(i.Tag)) == false)
ItemsList.RemoveAt(i.Index);
}
}


=======================
PROBLEM
Altought this proc is recursive, the FOREACH seems to not recalculate the
COUNT of the Items Collection at every run, so when I remove an item from
the list, I also pretty much screws the internal COUNT of the FOREACH.


=======================
SOLUTION
...hummm here is where you may put add some ideas... !!!


Thanks,
Filippo
 
Filippo,

You really shouldn't use foreach if you need to modify the contents of
the list (change the state of the enumeration) during the enumeration.
Since you need to remove items, I would recommend using a for loop, counting
backwards from the last item (so that when you remove an item, you don't
have to worry about indexes shifting), like so:

protected void AdjustMenuBasedOnUserSecurity(Items ItemsList)
{
// The item.
Item item;

for (int index = ItemsList.Count - 1; index >= 0; index--)
{
// Get the item.
item = ItemsList[index];

if (i.Items.Count > 0)
AdjustMenuBasedOnUserSecurity(i.Items);

if (i.Tag == null)
continue;

if (this.LoggedUser.HasPermission(Convert.ToInt32(i.Tag)) == false)
ItemsList.RemoveAt(index);
}
}

This should work. This assumes that you implement IList, and have an
indexer.

Hope this helps.
 
First, I do not think that you can even add or remove collection items in a
foreach loop.

One idea might be to use a simple "for" loop that counts backwards. That
way, when you remove an item, your next position is not affected by the fact
that there is one fewer items.
 
Back
Top