14

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.

1

3 Answers 3

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.

Sign up to request clarification or add additional context in comments.

4 Comments

You just use the Implementation of the Dictionary Class, so you are technically not implementing IEnumerator :-).
@I'm implementing it, by using dictionary class underneath.
@Sebastian - I did it for another collection here: stackoverflow.com/questions/3823848/… . HTH.
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.
7

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.

4 Comments

Like Tigran you just using the Enumator of the Dictionary Class.
Tried to implement one myself with your post, but noticed your current never gets incremented. I think you wanted that to do in MoveNext() ?
The variable 'current' has to be initialized with -1 (both in the constructor and in the Reset method).
This implementation is broken because it never increments current.
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()

1 Comment

I did not know this! Saves redundant effort, as IEnumerable<T> inherits from IEnumrable which creates an annoying mess.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.