[Hint] : Enumeration has changed exception
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.
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:
And finally you can do:
This is just example that can be useful for many people, use it at your own risk
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();
}
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;
}
Code:
foreach ( Mobile m in new Isolator( World.Mobiles.Values ) )
{
if ( /* condition */ )
{
m.Delete();
}
}