将扩展方法应用于接口。购物车示例

时间:2014-03-26 15:27:40

标签: asp.net-mvc

ShoppinCart模型:

            using System.Collections;
            using System.Collections.Generic;

            namespace LanguageFeatures.Models {

                public class ShoppingCart : IEnumerable<Product> {

                    public List<Product> Products { get; set; }

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

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

我的书正在使用此代码来解释扩展方法。我找到了确切含义:

public class ShoppingCart : IEnumerable<Product>

没有真正解释。这是否意味着ShoppingCart模型将从Product模型派生出来,还是比它更多?我知道IEnumerable适用于对象的迭代,并且GetEnumerator以某种方式促进了这些迭代。它根本没有真正解释的目的:

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

是或者为什么必须在那里。它在做什么?所有这些代码似乎与MyExtensionMethods模型中声明的扩展方法有很大关系:

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

用于获取购物车中所有商品的总价。扩展方法本身我觉得我理解。我从Adam Feeman的Pro ASP .NET MVC5第4章中获取的代码。

在控制器中使用扩展方法和购物车:

public ViewResult UseExtensionEnumerable() {

        IEnumerable<Product> products = new ShoppingCart {
            Products = new List<Product> {
                new Product {Name = "Kayak", Price = 275M},
                new Product {Name = "Lifejacket", Price = 48.95M},
                new Product {Name = "Soccer ball", Price = 19.50M},
                new Product {Name = "Corner flag", Price = 34.95M}
            }
        };

        // create and populate an array of Product objects
        Product[] productArray = {
            new Product {Name = "Kayak", Price = 275M},
            new Product {Name = "Lifejacket", Price = 48.95M},
            new Product {Name = "Soccer ball", Price = 19.50M},
            new Product {Name = "Corner flag", Price = 34.95M}
        };

        // get the total value of the products in the cart
        decimal cartTotal = products.TotalPrices();
        decimal arrayTotal = products.TotalPrices();

        return View("Result",
            (object)String.Format("Cart Total: {0}, Array Total: {1}",
                cartTotal, arrayTotal));
    }

感谢您发帖...

1 个答案:

答案 0 :(得分:2)

此代码中有两个GetEnumerator方法的原因是因为IEnumerable<T>本身正在实现IEnumerable接口(请注意此版本缺少泛型类型)。因此,您必须实现该方法的两个版本才能实现IEnumerable<T>

由于两种方法都具有相同的签名,因此必须明确地实现其中一个接口。这意味着调用此方法的唯一方法是通过所述接口的显式实例。在这种情况下,开发人员选择隐式实现IEnumerableIEnumerable<T>。最后,由于Enumerable.GetEnumerator()只是返回GetEnumerator()而没有先明确地将此实例强制转换为IEnumerable实例,因此最终调用IEnumerable<T>.GetEnumerator()方法,该方法隐式定义了几行以上。这基本上就像任何其他方法一样超载。