服务接口中的IList,ICollection或IEnumerable?

Ant*_*iry 4 c# asp.net-mvc

我正在建立一个用于使用ASP.NET MVC 5中的Entity Framework访问数据库的服务。因此,我首先使用他的界面编写了一个基本服务。但是我担心一件事。

通常,我IEnumerable<T>在界面中返回一个,但通常会导致ToList()代码中的调用。

所以我想知道在这样的接口中最好返回什么。我可以返回,IList但是恐怕可能太多了,我不需要附带的所有方法IList

这是我的代码:

public interface IBaseService<T>
{
    T Add(T obj);
    T Update(T obj);
    T Remove(string id);
    T Get(string id);

    ICollection<T> Find(Expression<Func<bool, T>> func);
    ICollection<T> GetAll();
}
Run Code Online (Sandbox Code Playgroud)

Evk*_*Evk 5

你之前这么说

通常,我在接口中返回IEnumerable,但这通常导致代码中的ToList()调用。

您必须找出为什么要调用ToList()结果。您可能(但不太可能)要修改结果(添加\删除项目)。从诸如Find或方法返回可修改的集合通常不是一个好习惯GetAll,但是您可以返回ICollection<T>IList<T>(如果您还需要通过索引器进行快速访问或在特定位置插入/删除)。

但是,您更有可能打电话来ToList找出其中有多少个元素和/或访问特定元素。如果你只需要Count-回报IReadOnlyCollection<T>延伸IEnumerable<T>与刚刚Count财产。如果您还需要通过索引器快速访问-返回IReadOnlyList<T>扩展IReadOnlyCollection<T>了索引器。

双方ArrayList<T>实现所有这些接口,所以你可以只返回这些类的是:

 static IReadOnlyList<string> Test() {
      return new string[0]; // fine
 }
Run Code Online (Sandbox Code Playgroud)

但是,当以List这种方式返回时,调用方可能会将其投射回IList<T>并仍然对其进行修改。通常这不是问题,但是如果要防止这种情况,请AsReadOnly在列表中使用(它不会将任何内容复制到新列表中,因此不必担心性能):

static IReadOnlyList<string> Test() {
      return new List<string>().AsReadOnly(); // not required but good practice
 }
Run Code Online (Sandbox Code Playgroud)