Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing IEnumerable with an Array

Tags:

c#

ienumerable

This is likely a simple syntax question, but I can't figure it out.

Normally, I would do this:

public class OrderBook : IEnumerable<PriceLevel>
{
    private readonly List<PriceLevel> PriceLevels = new List<PriceLevel>();

    public IEnumerator<PriceLevel> GetEnumerator()
    {
        return PriceLevels.GetEnumerator();
    }

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

But instead of a list, I want to use an array - like this:

public class ArrayOrderBook : IEnumerable<PriceLevel>
{
    private PriceLevel[] PriceLevels = new PriceLevel[500];

    public IEnumerator<PriceLevel> GetEnumerator()
    {
        return PriceLevels.GetEnumerator();
    }

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

The IEnumerator IEnumerable.GetEnumerator() seems to compile fine - but the public IEnumerator<PriceLevel> says that I need some kind of cast - what is the best way of doing this?

William

like image 960
William Avatar asked Jul 03 '12 20:07

William


2 Answers

Try this:

public class ArrayOrderBook : IEnumerable<PriceLevel>
{
    private PriceLevel[] PriceLevels = new PriceLevel[500];

    public IEnumerator<PriceLevel> GetEnumerator()
    {
        return PriceLevels.AsEnumerable().GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return PriceLevels.GetEnumerator();
    }
}
like image 74
Filip Ekberg Avatar answered Sep 22 '22 08:09

Filip Ekberg


As you can see from your own IEnumerable<T> implementation, you need to provide both a generic and non-generic version of the method to fulfill the interface. In order to do this, since the methods have the same signature, one of them needs to be an explicit interface implementation. In the case of List, the generic version is a method in the class and the non-generic version is an explicit interface definition, since the generic version is generally more useful. In the case of an array, it already had the non-generic version as the implementation, and it was adding the generic version of the method in a subsequent version. To avoid the breaking change, the generic version is the explicit interface definition instead.

There are a number of ways of solving this issue. Here are three simple ones.

public IEnumerator<PriceLevel> GetEnumerator()
{
    return PriceLevels.AsEnumerable().GetEnumerator();
}


public IEnumerator<PriceLevel> GetEnumerator()
{
    IEnumerable<PriceLevel> enumerator = PriceLevels;
    return enumerator.GetEnumerator();
}

public IEnumerator<PriceLevel> GetEnumerator()
{
    return ((IEnumerable<PriceLevel>)PriceLevels).GetEnumerator()
}
like image 31
Servy Avatar answered Sep 22 '22 08:09

Servy