c# - 如果实现接口(interface)的类将使用 List<T>,为什么还要在接口(interface)定义中使用 IEnumerable<T>?

标签 c# asp.net asp.net-web-api ienumerable

我目前正在学习位于 here 的 .NET Web API 教程.在示例中,我们在模型类中定义了一个接口(interface),如下所示:

namespace ProductStore.Models
{
    public interface IProductRepository
    {
        IEnumerable<Product> GetAll();
        Product Get(int id);
        Product Add(Product item);
        void Remove(int id);
        bool Update(Product item);
    }
}

然后,在本教程的后面,我们将像这样实现这个接口(interface):

namespace ProductStore.Models
{
    public class ProductRepository : IProductRepository
    {
        private List<Product> products = new List<Product>();
        private int _nextId = 1;

        public ProductRepository()
        {
            Add(new Product { Name = "Tomato soup", Category = "Groceries", Price = 1.39M });
            Add(new Product { Name = "Yo-yo", Category = "Toys", Price = 3.75M });
            Add(new Product { Name = "Hammer", Category = "Hardware", Price = 16.99M });
        }

        public IEnumerable<Product> GetAll()
        {
            return products;
        }

        public Product Get(int id)
        {
            return products.Find(p => p.Id == id);
        }

        public Product Add(Product item)
        {
            if (item == null)
            {
                throw new ArgumentNullException("item");
            }
            item.Id = _nextId++;
            products.Add(item);
            return item;
        }

        public void Remove(int id)
        {
            products.RemoveAll(p => p.Id == id);
        }

        public bool Update(Product item)
        {
            if (item == null)
            {
                throw new ArgumentNullException("item");
            }
            int index = products.FindIndex(p => p.Id == item.Id);
            if (index == -1)
            {
                return false;
            }
            products.RemoveAt(index);
            products.Add(item);
            return true;
        }
    }
}

我的问题是,为什么接口(interface)写成GetAll()返回 IEnumerable<Product>如果实现要专门在 List<Product> 上运行?

我假设这是为了便于重用,以便其他一些 IProductRepository实现可以使用不同的 IEnumerable<Product> (虽然这样的例子会很好,因为我想不出一个,不是我怀疑它存在,我只是不是很有经验)。

假设重用确实是目标,那么为什么要这样写实现:

public IEnumerable<Product> GetAll()
{
    return products;
}

而不是像这样:

public List<Product> GetAll()
{
    return products;
}

框架或编译器没有能力看到public List<Product> GetAll()吗?可从 public IEnumerable<Product> GetAll() 导出?

最佳答案

两个主要原因:

  • 这隐藏了实际的实现,这样消费者就不会对数据做任何他们不应该做的事情(例如,直接从列表中添加或删除项目)。显然,消费者可以将结果转换为List<T>。 ,但他们将依赖于未记录的实现细节,因此如果您稍后更改它并破坏了他们的代码,那将是他们的错。
  • 如果有一天您需要更改实现以使用 List<T> 以外的东西,您可以在不对消费者造成任何可见变化的情况下做到这一点。

关于c# - 如果实现接口(interface)的类将使用 List<T>,为什么还要在接口(interface)定义中使用 IEnumerable<T>?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21609858/

相关文章:

c# - SignalR 帮助将 List<string> 传递给客户端

asp.net - 如何使用 Microsoft 帐户对我的网站进行身份验证

javascript - 显示用户是否通过身份验证的 View

c# - 如何在 Web API 应用程序中使用 ASP.net 5 Identity?基于 token 的用户认证。移动应用

c# - 两个列表框,一个在 javascript 中的选择

c# - 是否可以使用 System.Net.Http.HttpClient 的持久连接?

c# - 去 - 斯卡拉 - 去!主要区别是什么?

c# - 在 C# 中格式化 Excel 中多行的最快方法

c# - 序列化混淆类 C#

javascript - 如何使用 javascript 和 asp 文本框的 onchange 事件更改 asp 标签的可见性