Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Collection initializer for wrapper class and avoiding boxing of IEnumerator<T>

I have a wrapper struct for a Dictionary and I want to add a collection initializer to this class that adds my entries to the wrapped Dictionary.

public readonly struct Wrapper : IEnumerable<KeyValuePair<string, string>>
{
    public Dictionary<string, string> Instance { get; }

    public Wrapper()
    {
        Instance = new Dictionary<string, string>();
    }

    public void Add(string key, string value)
    {
        Instance.Add(key, value);
    }

    public IEnumerator<KeyValuePair<string, string>> GetEnumerator()
    {
        return Instance.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

However, GetEnumerator call will cause boxing as Dictionary‘s enumerator is a struct. Is there any way around this?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

The built-in Dictionary‘s implementations of IEnumerable.GetEnumerator and IEnumerable<KeyValuePair<TKey, TValue>>.GetEnumerator box the return value too. It can’t not do that, since IEnumerable requires you to return an interface type.

It’s just that Dictionary also defines its own GetEnumerator, that is not required by IEnumerable or IEnumerable<T>. This GetEnumerator returns the struct directly, without boxing.

So when you call GetEnumerator through the IEnumerator interface, the return value will still be boxed. It’s only when you call GetEnumerator directly on a dictionary, that it will not be boxed.

If that’s what you are after, you can do what Dictionary does and declare three methods too:

IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();

IEnumerator<KeyValuePair<string, string>> IEnumerable<KeyValuePair<string, string>>.GetEnumerator()
    => GetEnumerator();

public Dictionary<string, string>.Enumerator GetEnumerator()
    => Instance.GetEnumerator();

See also the source code of Dictionary in .NET, especially lines 1132, 365, and 367, where the 3 methods are declared.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading