Sometimes you need in your custom scripts to iterate for example through the World.Mobiles or World.Item hashtables and delete certain entry on the fly. But you can't do that since you can't change collection ( hashtable ) while iterating through it.
One way how to do it is write an array where you temporarily store objects to be deleted.
Code:
public ArrayList toDelete;
foreach ( Mobile m in World.Mobiles.Values )
{
if ( /* condition */ )
toDelete.Add ( m );
}
foreach ( Mobile m in toDelete )
{
m.Delete();
}
But its too unpractical to write it again and again for every single script.
Easier way to do it is by isolating the enemuration from the collection using custom enumerator:
Code:
public class Isolator : IEnumerable
{
internal class IsolatorEnumerator : IEnumerator
{
ArrayList items = new ArrayList();
int currentItem;
internal IsolatorEnumerator( IEnumerator enumerator )
{
while ( enumerator.MoveNext() != false )
{
items.Add( enumerator.Current );
}
IDisposable disposable = enumerator as IDisposable;
if ( disposable != null )
{
disposable.Dispose();
}
currentItem = -1;
}
public void Reset( )
{
currentItem = -1;
}
public bool MoveNext( )
{
currentItem++;
if ( currentItem == items.Count )
return false;
return true;
}
public object Current
{
get
{
return items[currentItem];
}
}
}
public Isolator( IEnumerable enumerable )
{
this.enumerable = enumerable;
}
public IEnumerator GetEnumerator( )
{
return new IsolatorEnumerator( enumerable.GetEnumerator() );
}
IEnumerable enumerable;
}
And finally you can do:
Code:
foreach ( Mobile m in new Isolator( World.Mobiles.Values ) )
{
if ( /* condition */ )
{
m.Delete();
}
}
This is just example that can be useful for many people, use it at your own risk
