Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IEnumerable<int> Requires also the Non generic IEnumerator?

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) ?

enter image description here

like image 530
Royi Namir Avatar asked Nov 27 '11 14:11

Royi Namir


People also ask

Is IEnumerable generic?

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.

What is difference between IEnumerable and IEnumerator in C#?

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 .

What is IEnumerable interface in C#?

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.

What is an IEnumerator?

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.


3 Answers

  1. The foreach keyword does not require the collection to implement IEnumerable at all; rather, it will call any defined GetEnumerator methods.

  2. IEnumerable<T> implements IEnumerable for compatibility reasons.

  3. 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:
like image 88
SLaks Avatar answered Oct 19 '22 16:10

SLaks


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.

like image 30
Adam Ralph Avatar answered Oct 19 '22 15:10

Adam Ralph


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
}
like image 4
CodesInChaos Avatar answered Oct 19 '22 15:10

CodesInChaos