【发布时间】:2016-03-25 13:23:39
【问题描述】:
当我在 C# 中有一个 ICollection<T> 变量时,我无法将它传递给需要 IReadOnlyCollection<T> 的函数:
public void Foo()
{
ICollection<int> data = new List<int>();
// Bar(data); // Not allowed: Cannot implicitly cast ICollection<int> to IReadOnlyCollection<int>
Bar(data.ToList()); // Works, since List<T> implements IReadOnlyCollection<T>
}
public void Bar(IReadOnlyCollection<int> data)
{
if (data.Count == 1) { /* ... */ }
// ...
}
显然问题在于ICollection<T> 不继承自IReadOnlyCollection<T> - 但为什么呢? ICollection<T> 应该是 IReadOnlyCollection<T> 的完整功能集以及修改集合的函数。
传递参数的最佳解决方案是什么?
一方面,由于我不想更改 Bar 中的集合,只需要计数和迭代集合,因此我需要 IReadOnlyCollection。
另一方面,我不想每次调用该函数时都创建一个新的列表对象。
【问题讨论】:
-
你到底在用那个方法收集什么?只是检查计数?可能有更好的方法来处理这种情况。
-
当你不希望你的类之外的任何东西修改你的集合时,你真的只使用 ReadOnlyCollection。如果它一开始就不是公共财产,那么担心就变得微不足道了。
-
@M.kazemAkhgary 如果有人通过
ICollection而不是IReadOnlyCollection,这只是在运行时中断。 -
@JeffMercado
ICollection<T>是分层数据结构中的Children(只读)属性,因此允许修改集合是有意的。但是,我不需要在评估树的上下文中修改它们,所以我想将我的功能限制在最严格的界面。Count == 1的情况是一种特殊处理,当只有一个子节点时,会跳过整个层级。 -
@Xcalibur37 我认为这有点短视。接受
IReadOnlyCollection<T>的方法表示该方法不会修改集合。
标签: c# icollection