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 次 |
最近记录: |