Ale*_*fie 29 .net c# vb.net design-principles
在我工作的许多项目中,每当我必须返回一个只读集合时,我使用该IEnumerable<T>
接口并使其类型特定如下:
Public ReadOnly Property GetValues() As IEnumerable(Of Integer)
Get
'code to return the values'
End Get
End Property
Run Code Online (Sandbox Code Playgroud)
大多数时候,我返回一个List但是在一些函数和只读属性中我返回一个数组,这个数组也可以通过扩展方法的礼貌来达到目的.
我的问题是我会通过返回违反任何设计原则IEnumerable<T>
s,而不是特定类型(例如:List<T>
,HashSet<T>
,Stack<T>
或Array
S) ?
Dav*_*vid 34
我通常也喜欢IEnumerable<T>
.主要的是问自己从方法返回的实际(甚至是最小)功能(或者在方法参数的情况下传递给它).
如果你需要做的只是对结果集进行枚举,那么IEnumerable<T>
就完全如此.不多也不少.这使您可以灵活地在某些情况下返回更多特定类型,如果需要,而不会破坏方法的足迹.
Dom*_*nic 17
大卫的回答几乎涵盖了它; IEnumerable<T>
一般来说是最好的做法.您可以通过查看大多数较新的框架方法来看到这一点.
我只是想补充一点,因为你指定只读集合在你原来的问题,你可以通过调用执行这.ToList().AsReadOnly()
在您IEnumerable<T>
返回之前的实例.这将创建一个ReadOnlyCollection<T>
让您返回的具体实例.您的返回类型仍然是IEnumerable<T>
,因为呼叫者不需要知道您是专门返回的ReadOnlyCollection<T>
,但是这样可以防止呼叫者在脚中射击.
(如果没有这个步骤,调用者可以尝试将IEnumerable<T>
它从你的方法转换为List<T>
.如果转换成功,那么如果这是你最初使用的那个,那么调用者可以修改你在里面操作的相同列表你的方法,可能会产生意想不到的后果.)
Joe*_*Joe 14
就个人而言,我认为IEnumerable<T>
从API 返回是一个强烈暗示,实现可能会使用延迟评估.
知道可以使用延迟评估对于调用者来说可能很重要,因为它意味着:
多次迭代结果(例如,获得计数然后访问数据)将导致评估不止一次.
迭代结果时,可以从API抛出异常:
例如
IEnumerable<MyObject> LazyEvaluatedApi()
{
}
...
IEnumerable<MyObject> result = LazyEvaluatedApi();
...
foreach(MyObject item in result) // Exception from LazyEvaluatedApi may be thrown here.
{
}
Run Code Online (Sandbox Code Playgroud)
如果您认为任何实现都不需要使用延迟评估(例如数据访问层API),我宁愿返回ICollection<T>
或IList<T>
.除了让调用者访问Count
属性(ICollection<T>
和IList<T>
)和索引器(IList<T>
仅限)之外,您还清楚地表明不会进行惰性求值.
返回你的ICollection<T>
或者IList<T>
,你的具体实现通常可能会返回一个List<T>
.如果列表是只读的重要,那么返回List<T>.AsReadOnly()