是否有任何理由以暴露内部集合为ReadOnlyCollection而不是一个IEnumerable如果调用代码仅在收集迭代?

class Bar
{
    private ICollection<Foo> foos;

    // Which one is to be preferred?
    public IEnumerable<Foo> Foos { ... }
    public ReadOnlyCollection<Foo> Foos { ... }
}


// Calling code:

foreach (var f in bar.Foos)
    DoSomething(f);

正如我看到它的IEnumerable是ReadOnlyCollection的接口的子集,它不允许用户修改的集合。因此,如果IEnumberable接口足够然后就是使用一个。是推理它还是我失去了一些东西?有道

感谢/埃里克

其他提示

如果您只需要通过收集迭代:

foreach (Foo f in bar.Foos)

然后返回的的IEnumerable 就足够了。

如果你需要的物品随机访问:

Foo f = bar.Foos[17];

然后再包上的 ReadOnlyCollection

如果你这样做,那么还有什么能阻止你的来电铸造了IEnumerable返回的ICollection,然后修改它。 ReadOnlyCollection消除这种可能性,尽管它仍然可以通过反射来访问底层写集合。如果集合较小,则一种安全,简便的方法来解决这个问题是返回一个复印件。

我避免使用ReadOnlyCollection尽可能,它实际上是比只用一个正常的列表相当慢。 看到这个例子:

List<int> intList = new List<int>();
        //Use a ReadOnlyCollection around the List
        System.Collections.ObjectModel.ReadOnlyCollection<int> mValue = new System.Collections.ObjectModel.ReadOnlyCollection<int>(intList);

        for (int i = 0; i < 100000000; i++)
        {
            intList.Add(i);
        }
        long result = 0;

        //Use normal foreach on the ReadOnlyCollection
        TimeSpan lStart = new TimeSpan(System.DateTime.Now.Ticks);
        foreach (int i in mValue)
            result += i;
        TimeSpan lEnd = new TimeSpan(System.DateTime.Now.Ticks);
        MessageBox.Show("Speed(ms): " + (lEnd.TotalMilliseconds - lStart.TotalMilliseconds).ToString());
        MessageBox.Show("Result: " + result.ToString());

        //use <list>.ForEach
        lStart = new TimeSpan(System.DateTime.Now.Ticks);
        result = 0;
        intList.ForEach(delegate(int i) { result += i; });
        lEnd = new TimeSpan(System.DateTime.Now.Ticks);
        MessageBox.Show("Speed(ms): " + (lEnd.TotalMilliseconds - lStart.TotalMilliseconds).ToString());
        MessageBox.Show("Result: " + result.ToString());
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top