Can Anyone Explain Ienumerable and Ienumerator to Me

Can anyone explain IEnumerable and IEnumerator to me?

for example, when to use it over foreach?

You don't use IEnumerable "over" foreach. Implementing IEnumerable makes using foreach possible.

When you write code like:

foreach (Foo bar in baz)
{
...
}

it's functionally equivalent to writing:

IEnumerator bat = baz.GetEnumerator();
while (bat.MoveNext())
{
bar = (Foo)bat.Current
...
}

By "functionally equivalent," I mean that's actually what the compiler turns the code into. You can't use foreach on baz in this example unless baz implements IEnumerable.

IEnumerable means that baz implements the method

IEnumerator GetEnumerator()

The IEnumerator object that this method returns must implement the methods

bool MoveNext()

and

Object Current()

The first method advances to the next object in the IEnumerable object that created the enumerator, returning false if it's done, and the second returns the current object.

Anything in .Net that you can iterate over implements IEnumerable. If you're building your own class, and it doesn't already inherit from a class that implements IEnumerable, you can make your class usable in foreach statements by implementing IEnumerable (and by creating an enumerator class that its new GetEnumerator method will return).

Why do we need IEnumerator and IEnumerable?

I was however able to iterate through a custom collection without the use of either

Of course you can iterate your own collection without the interface; if you couldn't, then how would you implement the interface?

You, as a code implementor, do not implement an interface for your convenience. You implement it for the convenience of the consumer of your code. The interface means "attention customer: you can enumerate the contents of this collection without having to know anything about how I implemented it".

That's the purpose of an interface: it provides an abstraction that allows consumers of your code to use it without having to understand how it works.

What is the difference between IEnumerator and IEnumerable?

IEnumerable is an interface that defines one method GetEnumerator which returns an IEnumerator interface, this in turn allows readonly access to a collection. A collection that implements IEnumerable can be used with a foreach statement.

Definition

IEnumerable 

public IEnumerator GetEnumerator();

IEnumerator

public object Current;
public void Reset();
public bool MoveNext();

example code from codebetter.com

What is the reason implementing IEnumerable and IEnumerator

The correct answer is a and this is clear if you take a look at the definitions of the interfaces:

[GuidAttribute("496B0ABE-CDEE-11d3-88E8-00902754C43A")]
[ComVisibleAttribute(true)]
public interface IEnumerable
{
IEnumerator GetEnumerator();
}

And

[ComVisibleAttribute(true)]
[GuidAttribute("496B0ABF-CDEE-11d3-88E8-00902754C43A")]
public interface IEnumerator
{
Object Current { get; }
bool MoveNext();
void Reset();
}

As you notice here, when a type implements the IEnumerable interface, it should have a method that will return a Enumerator, an object that implements the IEnumerator interface.

Then the interface called IEnumerator has one property that holds the current object, when we iterate through a collection and two methods, the MoveNext and the Reset. Under the hood, when we iterate through a collection the Iterator's method called MoveNext is called at first. If this is true we get the first element -- that's the current object. Then method called MoveNext is get called again and again until it returns false. Each time MoveNext is called we get an object from the collection, we iterate through.

Why do we have the Reset method?

As it is stated in MSDN:

Sets the enumerator to its initial position, which is before the first
element in the collection.

IEnumerable and IEnumerator, or foreach C#

If I can do the same with the foreach loop, Why Do I have to use the
interfaces IEnumerable and IEnumerator?

Except for the array, foreach loop utilises the IEnumerable and IEnumerator to display/perform the operations.

But, you cannot exactly modify the element itself using foreach loop, that is only possible on an Enumerator(Iterator in Java). You cannot remove the element using foreach loop.

What is better in performance?

Stick to the foreach loop as you shouldn't reinvent the wheel, unless you have to modify the element from the collection.

Imagine, I am doing a program which spell each letter of a big text,
What Would I have to use? Interfaces or foreach loop?

This is the case where you should simply use foreach loop as you only need to spell each letter of a text, which is a string. You're not modifying the string (not creating a new string) itself.

IEnumerable & IEnumerator

Generally, an IEnumerable is an object which can be enumerated, such as a list or array. An IEnumerator is an object that stores the state of the enumeration.

The reason they're not one and the same is that you could have multiple enumerations over the same object at the same time - even in a single-threaded application. For example, consider the following code:

foreach (x in mylist)
{
foreach (y in mylist)
{
if (x.Value == y.Value && x != y)
{
// Found a duplicate value
}
}
}

This would work fine if mylist is a proper implementation of IEnumerable, but it would fail if mylist returned itself as the enumerator.

Understanding IEnumerable - IEnumerator logic

First of all I don't understand how c# knows MyExtensionMethods is an extension of ShoppingCart

it isn't; the "magic" here is the this IEnumerable<Product> products, which says "the method is an extension method on anything that is IEnumerable<Product>" - and since ShoppingCart satisfies that, it works.

then I don't understand how can TotalPrices know that prod come from Products in ShoppingCart class

It doesn't access Products on ShoppintCart; it goes via GetEnumerator();
this works because foreach (Product prod in products) can work on (among other things) something that is IEnumerable<Product> - which we know products is, because that is how it is defined. This basically then becomes:

    public static decimal TotalPrices (this IEnumerable<Product> products)
{
decimal total = 0;
using (var iter = products.GetEnumerator())
{
while (iter.MoveNext())
{
var prod = iter.Current;
total += prod?.Price ?? 0;
}
}
return total;
}

which is all defined via IEnumerable<T>. The good news is: you usually never need to know this - just know that foreach works on sequences, and IEnumerable<T> is a sequence of T.

Why is IEnumerable T necessary when there is IEnumerator T ?

The two interfaces each represent very different concepts. IEnumerable<T> is something that "allows enumeration", where IEnumerator<T> is the representation of the enumeration itself.

If you were to merge these together, it would be impossible to enumerate a single collection more than once at the same time (without some other mechanism in place). For example, two threads doing a foreach over an array would no longer work, where that is perfectly acceptable in the current design.

Why does interface IEnumerable return IEnumerator GetEnumemrator()? Why not just implement interface IEnumerator?

You can check the differences at this very nice article

TL;DR - Effectively, the IEnumerable contract assumes that you have a way of maintaning the state of the Enumerable.

Similarities

Both of these interfaces help to loop through the collection.

Relation

The IEnumerable interface actually uses IEnumerator. The main reason to create an IEnumerable is to make the syntax shorter and simpler.

If you go to the definition of the IEnumerable interface, you will see this interface has a method GetEnumerator() that returns an IEnumerator object back.

Differences

The main difference between IEnumerable and IEnumerator is an IEnumerator retains its cursor's current state.

When to use:

So, if you want to loop sequentially through the collection, use an IEnumerable interface else if you want to retain the cursor position and want to pass it from one function to another function then use an IEnumerator interface.

Example:

static void iEnumeratorMethodOne(IEnumerator<string> i)  
{
while(i.MoveNext())
{
Console.WriteLine(i.Current);

if(i.Current == "June")
{
iEnumeratorMethodTwo(i);
}
}
}

static void iEnumeratorMethodTwo(IEnumerator<string> i)
{
while(i.MoveNext())
{
Console.WriteLine(i.Current);
}
}


Related Topics



Leave a reply



Submit