13

How to implement IEnumerator on this class so that I can use it in foreach loop.

public class Items
    {
        private Dictionary<string, Configuration> _items = new Dictionary<string, Configuration>();

        public Configuration this[string element]
        {
            get
            {

                if (_items.ContainsKey(element))
                {
                    return _items[element];
                }
                else
                {
                    return null;
                }
            }

            set
            {
                _items[element] = value;
            }
        }
   }

In this example Configuration is a simple class with few properties.

Riz
  • 6,746
  • 16
  • 67
  • 89
  • possible duplicate of [How would you implement the IEnumerator interface?](http://stackoverflow.com/questions/53967/how-would-you-implement-the-ienumerator-interface) – Alastair Pitts Aug 02 '11 at 07:10

3 Answers3

16

Just an example to implement typesafe IEnumerable and not IEnumerator which you will be able to use in foreach loop.

   public class Items : IEnumerable<Configuration>
    {
        private Dictionary<string, Configuration> _items = new Dictionary<string, Configuration>();


        public void Add(string element, Configuration config) {
            _items[element] = config;
        }

        public Configuration this[string element]
        {
            get
            {

                if (_items.ContainsKey(element))
                {
                    return _items[element];
                }
                else
                {
                    return null;
                }
            }

            set
            {
                _items[element] = value;
            }
        }

        public IEnumerator<Configuration> GetEnumerator()
        {
            return _items.Values.GetEnumerator();
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return _items.Values.GetEnumerator();
        }
    }

Regards.

Tigran
  • 61,654
  • 8
  • 86
  • 123
  • 4
    You just use the Implementation of the Dictionary Class, so you are technically not implementing IEnumerator :-). – Sebastian Oct 25 '16 at 12:08
  • @I'm implementing it, by using dictionary class underneath. – Tigran Oct 25 '16 at 15:26
  • @Sebastian - I did it for another collection here: http://stackoverflow.com/questions/3823848/creating-a-very-simple-linked-list/42206589#42206589 . HTH. – jacoblambert Feb 14 '17 at 18:15
  • I comment here, because I used to always get this page via Google search whenever I wanted to implement an enumerator and was frustrated by what you point out. Thanks. – jacoblambert Feb 14 '17 at 18:37
6

You should be able to implement IEnumerator like this:

public class Items : IEnumerator<KeyValuePair<string, Configuration>>  
{        
    private Dictionary<string, Configuration> _items = new Dictionary<string, Configuration>();        
    public Configuration this[string element]       
    {            
        get
        {
            if (_items.ContainsKey(element))
            {
                return _items[element];
            }
            else
            {
                return null;
            }
        }
        set
        {
             _items[element] = value;
        }
    }

    int current;
    public object Current
    {
        get { return _items.ElementAt(current); }
    }

    public bool MoveNext()
    {
        if (_items.Count == 0 || _items.Count <= current)
        {
            return false;
        }
        return true;
    }

    public void Reset()
    {
        current = 0;
    }

    public IEnumerator GetEnumerator()
    {
        return _items.GetEnumerator();
    }

    KeyValuePair<string, Configuration> IEnumerator<KeyValuePair<string, Configuration>>.Current
    {
        get { return _items.ElementAt(current); }
    }

    public void Dispose()
    {
        //Dispose here
    }
}

But as already noted you could also just implement IEnumerable.

Simon Fischer
  • 3,816
  • 3
  • 23
  • 32
5

You don't need to implement IEnumerable or any interface. In order to be able to use your class in a foreach, all that you need is to add an instance method to your class with the follwing signature:

IEnumerator GetEnumerator()
nakhli
  • 4,009
  • 5
  • 38
  • 61
  • 1
    I did not know this! Saves redundant effort, as `IEnumerable` inherits from `IEnumrable` which creates an annoying mess. – Amir Abiri Jan 19 '17 at 10:19