3 questions :
1) why does the out put is taken from the NON generic function ?
2) why do I have to implement ALSO the NON generic function ?
3) What do I need to do if i want to see the Generic function output ( the int's) ?
IEnumerable interface is a generic interface which allows looping over generic or non-generic lists. IEnumerable interface also works with linq query expression. IEnumerable interface Returns an enumerator that iterates through the collection.
An IEnumerator is a thing that can enumerate: it has the Current property and the MoveNext and Reset methods (which in . NET code you probably won't call explicitly, though you could). An IEnumerable is a thing that can be enumerated...which simply means that it has a GetEnumerator method that returns an IEnumerator .
IEnumerable is an interface defining a single method GetEnumerator() that returns an IEnumerator interface. It is the base interface for all non-generic collections that can be enumerated. This works for read-only access to a collection that implements that IEnumerable can be used with a foreach statement.
IEnumerator is an interface, which when implemented allows you to iterate through the list of controls. To implement it requires that you provide two methods - Reset to go back to the beginning of the list, and MoveNext to move forward, and Current to get the current item.
The foreach
keyword does not require the collection to implement IEnumerable
at all; rather, it will call any defined GetEnumerator
methods.
IEnumerable<T>
implements IEnumerable
for compatibility reasons.
You should implement IEnumerable.GetEnumerator()
explicitly and have the normal method return IEnumerator<T>
.
If the class has a normal GetEnumerator()
method (as opposed to an explicit interface implementation), the compiler will call it.
The spec says:
- Otherwise, determine whether the type X has an appropriate GetEnumerator method:
- Perform member lookup on the type X with identifier GetEnumerator and no type arguments. If the member lookup does not produce a match, or it produces an ambiguity, or produces a match that is not a method group, check for an enumerable interface as described below. It is recommended that a warning be issued if member lookup produces anything except a method group or no match.
- Perform overload resolution using the resulting method group and an empty argument list. If overload resolution results in no applicable methods, results in an ambiguity, or results in a single best method but that method is either static or not public, check for an enumerable interface as described below. It is recommended that a warning be issued if overload resolution produces anything except an unambiguous public instance method or no applicable methods.
- [...]
- Otherwise, check for an enumerable interface:
1) The output is taken from the non generic function because it is defined implicitly (and the generic function is defined explicitly).
2) IEnumerable<T>
inherits from IEnumerable
, so any type inheriting from IEnumerable<T>
also has to implement the members of IEnumerable
3) Make the generic definition implicit and the non-generic definition explicit, e.g.
public class Class1 : IEnumerable<int>
{
public IEnumerator<int> GetEnumerator()
{
yield return 1;
yield return 2;
yield return 3;
yield return 4;
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
Note that you can return the generic enumerator from the non-generic method because IEnumerator<T>
inherits from IEnumerator
.
You need to implement both, since IEnumerable<T>
is derived from IEnumerable
. To call an explicitly implemented method you need to cast to that interface.
But usually you implement the non generic method explicitly and the generic method implicitly. That way foreach
will use the generic method. foreach
uses the GetEnumerator()
method on the type of the collection, and only falls back to the interface methods if this method is not present.
The typical implementation is:
public IEnumerator<int> GetEnumerator()
{
...
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();//Forward to strongly typed version
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With