tags:

views:

635

answers:

6

Hello!

I have an interface that, among other things, implements a "public IEnumerator GetEnumerator()" method, so I can use the interface in a foreach statement.

I implement this interface in several classes and in one of them, I want to return an empty IEnumerator. Right now I do this the following way:

public IEnumerator GetEnumerator()
{
    ArrayList arr = new ArrayList();
    return arr.GetEnumerator();
}

However I consider this an ugly hack, and I can't help but think that there is a better way of returning an empty IEnumerator. Is there?

A: 

You can make a NullEnumerator which implements the IEnumerator interface. You can just pass an instance off the NullEnumerator.

here is an example of an EmptyEnumerator

Ikke
+2  A: 

You should implement IEnumerator interface and IEnumerable, and return false from MoveNext function of IEnumerable interfase

private class EmptyEnumerator : IEnumerator
{


    public EmptyEnumerator()
    {
    }

    #region IEnumerator Members

    public void Reset() { }

    public object Current
    {
        get
        {
            throw new InvalidOperationException();
        }
    }
    public bool MoveNext()
    { return false; }
}


public class EmptyEnumerable : IEnumerable
{

    public IEnumerator GetEnumerator()
    {
        return new EmptyEnumerator();
    }
}
ArsenMkrt
According to MSDN documentation, Current should throw an exception in this case (http://msdn.microsoft.com/en-us/library/system.collections.ienumerator.current.aspx)
Konamiman
Ok thanks @Konamiman, corrected ;)
ArsenMkrt
+5  A: 

You could implement a dummy class that implements IEnumerator, and return an instance of it:

class DummyEnumerator : IEnumerator
{
    public object Current
    {
        get
        {
            throw new InvalidOperationException();
        }
    }

    public bool MoveNext()
    {
        return false;
    }

    public void Reset()
    {
    }
}
Konamiman
+16  A: 

This is simple in C# 2:

public IEnumerator GetEnumerator()
{
    yield break;
}

You need the yield break statement to force the compiler to treat it as an iterator block.

This will be less efficient than a "custom" empty iterator, but it's simpler code...

Jon Skeet
It's really pointless to try to compete with you in a C# question. :-)
Konamiman
@Konamiman: Not at all. Remember the LINQ question you answered and then deleted, spotting that the value of the attribute was required? I missed that!
Jon Skeet
+2  A: 

The way I use is to use the enumerator of an empty array:

public IEnumerator GetEnumerator() {
    return new object[0].GetEnumerator();
}

It can also be used for generic IEnumerator or IEnumerable (use an array of the appropriate type)

thecoop
+3  A: 

There is an extra function in the framework:

public static class Enumerable
{
    public static IEnumerable<TResult> Empty<TResult>();
}

you can write

var NullEnumerable = Enumerable.Empty<int>();