了解 IEnumerable - IEnumerator 逻辑

Understanding IEnumerable - IEnumerator logic

我被 Adam Freeman "Asp net" 这本书卡住了,我读了很多关于 IEnumerable 和 IEnumerator 接口的内容,但仍然很难理解一些结果。我有这两个 classes。

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

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

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

和第一个的扩展,

 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;
    }
}

产品很简单 class,带有一些字段,例如名称、价格等。 我有很多疑问。首先我不明白c#怎么知道MyExtensionMethods是ShoppingCart的扩展,然后我不明白TotalPrices怎么知道prod来自ShoppingCart class中的Products。有人能简单地解释一下这几行背后的逻辑吗?

谢谢大家,不好意思提问。

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

不是; "magic" 这里是 this IEnumerable<Product> products,它表示 "the method is an extension method on anything that is IEnumerable<Product>" - 因为 ShoppingCart 满足它,所以它有效。

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

不会访问ShoppintCart上的Products;它通过 GetEnumerator(); 这是有效的,因为 foreach (Product prod in products) 可以处理(除其他外)IEnumerable<Product> 的东西——我们知道 products 是,因为它是这样定义的。这基本上变成了:

    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;
    }

都是通过 IEnumerable<T> 定义的。好消息是:你 通常 永远不需要知道这一点 - 只需要知道 foreach 作用于序列,而 IEnumerable<T>T 的序列.