Reputation: 1
I am new to IEnumerable in C# and am confused when reading about how to implement it from multiple sources. Here is what I have gathered so far: (1) source 1: If a class implements IEnumerable, it must implement IEnumerator, which in turn must implement MoveNext, Reset methods too. This means I need have all of these in the class:
class Product : IEnumerable
{
...
public IEnumerator GetEnumerator()
{ return new ProductEnumerator();}
...
}
class ProductEnumerator : IEnumerator
{
...
public bool MoveNext()
{...}
public void Reset()
{...}
(2) Source 2: I can just simply use the below code and it is valid.
class Product
{
public IEnumerable<Product> GetProducts() {return new List<Product>{...}}
}
(3) Source 3: When implementing the GetEnumerator method:
IEnumerator IEnumerable.GetEnumerator()
{
return (Enumerator) GetEnumerator();
}
My questions here:
I am really quite confused and thanks for shining some light.
Upvotes: 0
Views: 434
Reputation: 186688
When we want to enumerate anything, we usually start from IEnumerable<T>
where T
is the type of items we want to enumerate.
Assuming that you have Product
which can contain (sub-) products in List<Product> items
class Product {
...
private List<Product> items = new List<Product>();
...
}
you can put it as (please, note that there's GetEnumerator
and no more methods)
// Note, that if class implements IEnumerable<T>
// it implements IEnumerable as well.
class Product : IEnumerable<Product> {
...
private List<Product> items = new List<Product>();
...
public IEnumerator<Product> GetEnumerator() {
throw new NotImplementedException();
}
// Usually, it's nothing more than boiler plate code:
// Having typed GetEnumerator (above) we return typeless
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
Now we should implement IEnumerator<Product> GetEnumerator()
method. We have two main options here:
use the collection:
...
// We want to enumerate items: let .Net do it for us
public IEnumerator<Product> GetEnumerator() => items.GetEnumerator();
...
or some Linq query, e.g.
...
// We want to enumerate items: let .Net do it for us
public IEnumerator<Product> GetEnumerator() => items
.Where(item => item.Name is not null) // Some condition here
.GetEnumerator();
...
Another possibility is to implement custom enumeration and then call it via GetEnumerator()
:
private Product MyEnumeration() {
foreach (var item in items) {
yield return item;
}
}
public IEnumerator<Product> GetEnumerator() => MyEnumeration().GetEnumerator();
Upvotes: 0