Dan*_*ner 3 c# collections ienumerable readonly-collection
我有方法将私有集合返回给调用者,我想阻止调用者修改返回的集合.
private readonly Foo[] foos;
public IEnumerable<Foo> GetFoos()
{
return this.foos;
}
Run Code Online (Sandbox Code Playgroud)
目前,私有集合是一个固定数组,但如果需要在运行时添加新项目,集合可能会成为一个列表.
有几种解决方案可以防止调用者修改集合.返回IEnumerable<T>是最简单的解决方案,但调用者仍然可以将返回值向上转换IList<T>并修改集合.
((IList<Foo>)GetFoos())[0] = otherFoo;
Run Code Online (Sandbox Code Playgroud)
克隆集合的明显缺点是有两个集合可以独立发展.到目前为止,我已经考虑了以下选项.
ReadOnlyCollection<T>.Enumerable通过执行类似的虚拟投影返回由类定义的LINQ迭代器之一list.Select(item => item).实际上我考虑使用Where(item => true)因为返回的迭代器似乎更轻量级.我不喜欢使用ReadOnlyCollection<T>它是它实现IList<T>和调用Add()或访问索引器将导致异常.虽然这在理论上是绝对正确的,但几乎没有真正的代码检查IList<T>.IsReadOnly或IList<T>.IsFixedSize.
使用LINQ迭代器 - 我将代码包装在扩展方法中MakeReadOnly()- 防止这种情况,但它有一个黑客的味道.
编写自定义包装器?重新发明轮子?
有任何想法,考虑或其他解决方案吗?
在标记这个问题时,我发现了之前没有注意到的Stack Overflow问题.Jon Skeet也建议使用"LINQ hack",但使用效率更高Skip(0).
不幸的是没有办法实现正是你在找什么在框架的当前版本.它根本没有具体类型和接口样式的可索引不可变/只读集合的概念.
正如您所指出的,ReadOnlyCollection<T>在混凝土类型方面可以正常工作.但是没有相应的接口可以实现,这也是静态只读的.
你真正的选择是......
IEnumerable<T>或定义集合实现的需要只读接口.| 归档时间: |
|
| 查看次数: |
1226 次 |
| 最近记录: |