理解IEnumerable - IEnumerator逻辑

3

我陷入了Adam Freeman的"Asp net"书中,我读了很多关于IEnumerable和IEnumerator接口的内容,但有些结果仍然很难理解。我有这两个类。

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

Product是一个简单的类,拥有一些字段如名称、价格等。我有很多疑问。首先,我不明白C#如何知道MyExtensionMethods是ShoppingCart的扩展,然后我也不明白TotalPrices如何知道prod来自ShoppingCart类中的Products。能否有人简要地解释一下这几行代码背后的逻辑呢?

谢谢大家,抱歉我的问题有点愚蠢。


TotalPricesIEnumerable<Product>的扩展方法,ShoppingCart实现了这个接口。 - Pavel Anikhouski
1个回答

3
首先,我不明白c#如何知道MyExtensionMethods是ShoppingCart的扩展。
实际上它并不是;这里的"魔法"在于this IEnumerable<Product> products,它表示"该方法是任何实现了IEnumerable<Product>的东西的扩展方法" - 因为ShoppingCart满足这个条件,所以它能够工作。
然后,我不明白TotalPrices如何知道prod来自ShoppingCart类中的Products。
它并没有访问ShoppingCart中的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 元素的序列。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接