我正在使用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();
}
答案 0 :(得分:5)
你说那个
通常我会在界面中返回IEnumerable,但这通常会 导致代码中的ToList()调用。
您必须找到为什么您在结果上调用ToList()
。您想要修改结果(添加\删除项目)是可能的,但不太可能。从Find
或GetAll
等方法返回可修改集合通常不是一个好习惯,但您可以返回ICollection<T>
或IList<T>
(如果您还需要快速通过索引器访问或在特定位置插入\ remove。)
然而,您更有可能致电ToList
以确定存在多少元素和/或访问特定元素。如果您只需要Count
- 请返回IReadOnlyCollection<T>
,其IEnumerable<T>
仅使用Count
属性。如果您还需要通过索引器快速访问 - 请使用索引器返回IReadOnlyList<T>
IReadOnlyCollection<T>
。
Array
和List<T>
都实现了所有这些接口,因此您可以按原样返回这些类:
static IReadOnlyList<string> Test() {
return new string[0]; // fine
}
但是,以这种方式返回List
时,调用者可能会将其强制转换回IList<T>
并仍然对其进行修改。这通常不是问题,但如果你想阻止它,请在列表中使用AsReadOnly
(它不会将任何内容复制到新列表中,因此不要担心性能):
static IReadOnlyList<string> Test() {
return new List<string>().AsReadOnly(); // not required but good practice
}
答案 1 :(得分:2)
这取决于你的意图。在大多数情况下,您的返回类型可能应为IReadOnlyCollection<T>
。在极少数情况下,您希望调用者能够修改集合,您可以返回ICollection<T>
。仅当您确定调用者只需要向前迭代时才使用IEnumerable<T>
。
答案 2 :(得分:1)
我想最纯粹的解决方案是使用IEnumerable<T>
,但它归结为在解决方案中设置约定。如果您负责架构,那么您最好还是决定返回List<T>
,以便掌握更广泛的方法。