1

I often have to implement some interfaces such as IEnumerable<T> in my code.

Each time, when implementing automatically, I encounter the following:

public IEnumerator<T> GetEnumerator() {
    // Code here...
}

public IEnumerator GetEnumerator1() {
    // Code here...
}

Though I have to implement both GetEnumerator() methods, they impossibly can have the same name, even if we understand that they do the same, somehow. The compiler can't treat them as one being the overload of the other, because only the return type differs.

When doing so, I manage to set the GetEnumerator1() accessor to private. This way, the compiler doesn't complaint about not implementing the interface member, and I simply throw a NotImplementedException within the method's body.

However, I wonder whether it is a good practice, or if I shall proceed differently, as perhaps a method alias or something like so.

What is the best approach while implementing an interface such as IEnumerable<T> that requires the implementation of two different methods with the same name?

EDIT #1

Does VB.NET reacts differently from C# while implementing interfaces, since in VB.NET it is explicitly implemented, thus forcing the GetEnumerator1(). Here's the code:

Public Function GetEnumerator() As System.Collections.Generic.IEnumerator(Of T) Implements System.Collections.Generic.IEnumerable(Of T).GetEnumerator
    // Code here...
End Function

Public Function GetEnumerator1() As System.Collections.Generic.IEnumerator Implements System.Collections.Generic.IEnumerable.GetEnumerator
    // Code here...
End Function

Both GetEnumerator() methods are explicitly implemented, and the compile will refuse them to have the same name. Why?

Will Marcouiller
  • 23,773
  • 22
  • 96
  • 162
  • Well, it doesn't really matter here as it is an example to state what I'm trying to say. Please see my question edit. =) – Will Marcouiller Jun 01 '10 at 19:53
  • your VB method declarations explicitly implement *different* interfaces (generic and not generic versions of `IEnumerator`): are you saying that the compiler disallows those? – Jeff Sternal Jun 01 '10 at 19:58
  • @Jeff Sternal: Nope, those are correct. But I have never ever seen `GetEnumerator1()` member in a collection implementing `IEnumerable` in .NET, and it seems that they both can coexist. However, when I rename `GetEnumerator1()` to `GetEnumerator()`, there the compiler complaints, and I understand why. What I wonder is how to make the coexistence possible such as it is, if I remember correctly, such as it is in native .NET collections. – Will Marcouiller Jun 01 '10 at 20:04
  • @Jeff Sternal: When autoimplementing the IEnumerable(Of T) interface, VB.NET writes the two above-mentioned implementations, both the generic and the non-generic. What I wish to know is what is the favorited way to implement the interface in such situation. – Will Marcouiller Jun 01 '10 at 20:08

4 Answers4

6

You can use explicit interface implementation:

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

public IEnumerator<T> GetEnumerator()
{
    ...
}
Bryan Watts
  • 44,911
  • 16
  • 83
  • 88
3

In Visual Basic, all interface implementations are explicit.

Interface mappings are defined by the Implements statement so you can name your interface implementation methods whatever you want. (Unlike C#, where the compiler infers which methods implement interfaces by matching their names and signatures.)

Changing the method name and visibility (as appropriate) is standard practice in VB. See Implementing Interfaces in VB.NET for a good overview.

Jeff Sternal
  • 47,787
  • 8
  • 93
  • 120
  • I agree, but even, the compiler still complaint if I rename `GetEnumerator1()` to `GetEnumerator()`, as it has already a method named `GetEnumerator()`. What is the best solution/approach favorited by .NET in such scenarios? Thanks! =) – Will Marcouiller Jun 01 '10 at 19:59
1

You should be able to use Explicit Interface Implementations to create the two methods that have the same signature. Depending on what you are enumerating, I would just pass these calls through to an internal IEnumerable<T> such as a List or array.

John Bledsoe
  • 17,142
  • 5
  • 42
  • 59
0

Implementing the non-generic interface explicitly allows both methods to have the same name, and allows the non-generic version to be implemented in terms of the generic one. Along the lines of:

public class TestEnumerable : IEnumerable<int>
{
    public IEnumerator<int> GetEnumerator()
    {
        // Type-safe implementation here.
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}
Cumbayah
  • 4,415
  • 1
  • 25
  • 32