The other answers sort of miss the point.
Interfaces do not matter at all if the (compile-time) type of what is beeing foreach
ed has a public
non-generic non-static method called GetEnumerator
which takes zero arguments. (The return type of this method can be anything, generic or non-generic: interfaces will not matter.)
So the reason why the first of your methods is called, is that this is the public
method.
You can change that:
public class myWords : IEnumerable<string>
{
string[] f = "I love you".Split(new string[]{"lo"},StringSplitOptions.RemoveEmptyEntries);
IEnumerator<string> IEnumerable<string>.GetEnumerator()
{
return f.Select(s => s + "2").GetEnumerator();
}
public IEnumerator GetEnumerator()
{
return f.Select(s => s + "3").GetEnumerator();
}
}
To prove that interfaces are not needed, try this:
public class myWords // no interfaces!
{
string[] f = "I love you".Split(new string[]{"lo"},StringSplitOptions.RemoveEmptyEntries);
public IEnumerator GetEnumerator()
{
return f.Select(s => s + "3").GetEnumerator();
}
}
However, it is wise to implement IEnumerable<>
. Then your type can be used with Linq (extension methods on IEnumerable<>
), and can be used as argument to other methods that simply require an IEnumerable<>
.
Also, it is wise to have the method (or explicit interface implementation) that returns the non-generic IEnumerator
just call through to the method (or explicit interface implementation) that returns IEnumerator<>
. Having the two return distinct sequences is really confusing (but nice for asking and answering questions on how things work).
Current
property andMoveNext
method but doesn't implement any interfaces, and havemyWords
'GetEnumerator
method return that type rather thanIEnumerable
. – Valer