当我正在编写我的DAL或其他返回一组项目的代码时,我是否应该总是返回语句:
public IEnumerable<FooBar> GetRecentItems()
Run Code Online (Sandbox Code Playgroud)
要么
public IList<FooBar> GetRecentItems()
Run Code Online (Sandbox Code Playgroud)
目前,在我的代码中,我一直试图尽可能地使用IEnumerable,但我不确定这是否是最佳实践?这似乎是正确的,因为我返回了最通用的数据类型,同时仍然描述它的作用,但也许这是不正确的.
Sam*_*ron 65
当您需要返回可由调用者或ReadOnlyCollection为只读集合修改的集合时,框架设计指南建议使用类Collection.
这是一个简单的IList首选的原因是IList不通知调用者它是否只读.
如果您返回IList
,则某些操作可能对调用者来说有点棘手.此外,您不再为调用者提供修改集合的灵活性,这可能是您可能想要或不想要的.
请记住,LINQ包含一些技巧,并会根据执行的类型优化某些调用.因此,例如,如果您执行Count并且基础集合是List,则它不会遍历所有元素.
就个人而言,对于ORM,我可能会坚持IList
作为我的返回值.
Jon*_*jap 44
这实际上取决于您使用该特定界面的原因.
例如,IList<T>
有几种方法不存在于IEnumerable<T>
:
IndexOf(T item)
Insert(int index, T item)
RemoveAt(int index)
和属性:
T this[int index] { get; set; }
如果您以任何方式需要这些方法,那么一定要返回IList<T>
.
此外,如果使用您的IEnumerable<T>
结果的方法是期望的IList<T>
,它将保存CLR不考虑所需的任何转换,从而优化编译的代码.
Mel*_*Mel 22
通常,您应该要求最通用,并返回最具体的内容.因此,如果你有一个带参数的方法,并且你只需要IEnumerable中可用的那个,那么那应该是你的参数类型.如果您的方法可以返回IList或IEnumerable,则更喜欢返回IList.这确保了最广泛的消费者可以使用它.
在你需要的东西上松散,并明确你所提供的东西.
jer*_*jvl 20
那要看...
返回最少派生类型(IEnumerable
)将使您有最大的余地来改变轨道上的底层实现.
返回更多派生类型(IList
)可为API的用户提供更多结果操作.
我总是建议返回最少派生的类型,它包含你的用户将需要的所有操作......所以基本上,你首先必须在你定义的API的上下文中去除对结果的哪些操作有意义.
Joe*_*ler 11
需要考虑的一件事是,如果你使用延迟执行LINQ语句来生成你的IEnumerable<T>
,.ToList()
在你从方法返回之前调用意味着你的项可能被迭代两次 - 一次创建List,一次调用者循环,过滤或转换您的返回值.在实际应用中,我希望避免将LINQ-to-Objects的结果转换为具体的List或Dictionary,直到我不得不这样做.如果我的调用者需要一个List,那就是一个简单的方法调用 - 我不需要为他们做出这个决定,这使得我的代码在调用者只是做一个foreach的情况下稍微有效.
List<T>
为调用代码提供了更多功能,例如修改返回的对象和按索引访问.因此,问题可归结为:在您的应用程序的特定用例中,您是否希望支持此类用途(可能是通过返回一个新构建的集合!),以便调用者方便 - 或者您是否希望速度为简单的情况下所有调用者的需求是遍历集合,你可以安全地返回对真实底层集合的引用,而不用担心这会被错误地更改等等?
只有你能回答这个问题,并且只能理解你的呼叫者想要对返回值做什么,以及这里的性能有多重要(你要复制的集合有多大,这有多大可能成为瓶颈,等等).
小智 5
我认为您可以使用其中任何一种,但每种都有其用途。基本上
List
是,IEnumerable
但你有计数功能,添加元素,删除元素IEnumerable 对元素计数效率不高
如果集合是只读的,或者集合的修改是由 控制的,Parent
那么返回IList
just forCount
并不是一个好主意。
在 Linq 中,有一个Count()
扩展方法,如果基础类型为,则IEnumerable<T>
CLR 内部将快捷地调用该扩展方法,因此性能差异可以忽略不计。.Count
IList
一般来说,我认为(意见)最好在可能的情况下返回 IEnumerable,如果您需要进行添加,则将这些方法添加到父类中,否则使用者将在模型中管理集合,这违反了原则,例如违反了manufacturer.Models.Add(model)
法则德米特。当然,这些只是指导方针,并不是硬性规定,但在您完全掌握适用性之前,盲目遵循比根本不遵循要好。
public interface IManufacturer
{
IEnumerable<Model> Models {get;}
void AddModel(Model model);
}
Run Code Online (Sandbox Code Playgroud)
(注意:如果使用 nNHibernate,您可能需要使用不同的访问器映射到私有 IList。)
归档时间: |
|
查看次数: |
36764 次 |
最近记录: |