我目前正在学习位于 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/