Question

I'm trying to port some code that uses Hashtable to an environment that doesn't have this class. So I thought about not messing with the code and just create my own Hashtable from Dictionary, like this:

public class Hashtable : Dictionary<Object, Object> {
    // ...
    new public IDictionaryEnumerator GetEnumerator() {          

      var ie = base.GetEnumerator();
      while (ie.MoveNext())
          yield return new DictionaryEntry(ie.Current.Key, ie.Current.Value);
    }
}

I'm getting this error:

error CS1624: The body of 'System.Collections.Hashtable.GetEnumerator()' cannot be an iterator block because 'System.Collections.IDictionaryEnumerator' is not an iterator interface type

Well, but IDictionaryEnumerator inherits from IEnumerator.

The odd thing is that if I just return (IDictionaryEnumerator)base.GetEnumerator(); the code compiles (but fails during runtime in the foreach loop).

I don't understand what this error is telling me and don't know how to properly implement this.

Était-ce utile?

La solution

Iterator blocks are rewritten by the compiler into classes that implement IEnumerable or IEnumerator; the compiler doesn't know how to generate a class that implement IDictionaryEnumerator, so you can't use an iterator block to implement that interface.

A possible workaround is to provide your own implementation of IDictionaryEnumerator:

class Hashtable : Dictionary<object, object>
{
    new public IDictionaryEnumerator GetEnumerator()
    {
        return new DictionaryEnumerator(base.GetEnumerator());
    }

    struct DictionaryEnumerator : IDictionaryEnumerator
    {
        private Enumerator _en;

        public DictionaryEnumerator(Dictionary<object, object>.Enumerator en)
        {
            _en = en;
        }

        public object Current
        {
            get
            {
                return Entry;
            }
        }

        public DictionaryEntry Entry
        {
            get
            {
                var kvp = _en.Current;
                return new DictionaryEntry(kvp.Key, kvp.Value);
            }
        }

        public bool MoveNext()
        {
            bool result = _en.MoveNext();
            return result;
        }

        public void Reset()
        {
            throw new NotSupportedException();
        }

        public object Key
        {
            get
            {
                var kvp = _en.Current;
                return kvp.Key;
            }
        }

        public object Value
        {
            get
            {
                var kvp = _en.Current;
                return kvp.Value;
            }
        }
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top