RunUO Community

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

[Hint] : Enumeration has changed exception

arul

Sorceror
[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.
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 :p
 
Top