Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding IEnumerable - IEnumerator logic

I got stuck with Adam Freeman "Asp net" book, I read a lot about IEnumerable and IEnumerator interface, but it's still hard to understand some results. I have these two classes.

public class ShoppingCart : IEnumerable<Product>
{
    public IEnumerable<Product> Products { get; set; }

    public IEnumerator<Product> GetEnumerator()
    {
        return Products.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

and an extension of the first one,

 public static class MyExtensionMethods
{
    public static decimal TotalPrices (this IEnumerable<Product> products)
    {
        decimal total = 0;
        foreach (Product prod in products)
        {
            total += prod?.Price ?? 0;
        }
        return total;
    }
}

Product is an easy class with some fields like Name, Price etc. I have lot of doubts. First of all I don't understand how c# knows MyExtensionMethods is an extension of ShoppingCart, then I don't understand how can TotalPrices know that prod come from Products in ShoppingCart class. Could someone explain me briefly the logic behind these few lines?

Thank you everyone, sorry for the dumb question.

like image 701
anselboero Avatar asked Dec 20 '25 02:12

anselboero


1 Answers

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.

like image 129
Marc Gravell Avatar answered Dec 21 '25 20:12

Marc Gravell