47

List<T> implements IReadOnlyCollection<T> interface and provides the AsReadOnly() method which returns ReadOnlyCollection<T> (which in turn implements IReadOnlyCollection<T>).

What is the usage/reason for AsReadyOnly()? Its existence smells of one or two edge cases where just returning the list as IReadOnlyCollection<T> is just not good enough.

At first I though it may be to prevent casting the cost-ness away but it looks like you can do that with ReadOnlyCollection<T>'s Items accessor.

BTW. The documentation for ReadOnlyCollection<T> type reads

Provides the base class for a generic read-only collection.

which, in my head, conflicts with having a constructor described as

Initializes a new instance of the (...) class that is a read-only wrapper around the specified list.

Update: I did not see that ReadOnlyCollection<T>'s Items is protected.

4

2 回答 2

57

如果您只是将实际返回List<T>IReadOnlyList<T>,那么调用者始终可以将其转换回,然后根据需要修改列表。相反,调用AsReadOnly()会创建列表的只读包装器,消费者无法更新该包装器。

请注意,只读包装器将反映对基础列表所做的更改,因此可以访问原始列表的代码仍然可以在知道只读版本的任何消费者将看到这些更改的情况下对其进行更新。

于 2013-07-01T06:20:37.833 回答
27

首先,它不是AsReadOnly()添加的,因为IReadOnlyList<T>不够好 -IReadOnlyList<T>仅从 .NET 4.5 开始可用,而AsReadOnly()方法自 .NET 2 开始存在。

更重要的是:AsReadOnly()并且IReadOnlyList<T>服务于非常不同的目的。

ReadOnlyCollection<T>用于实现对象模型,例如Dictionary<K,V>.Keys和之类的东西Dictionary<K,V>.Values。这适用于消费者不应该能够更改内容而生产者可以更改内容的场景。它与Collection<T>它协同工作,为所有者提供挂钩,以在添加项目时验证更改或执行副作用。

IReadOnlyList<T>另一方面,它只是一个提供集合只读视图的接口。方法可以使用它来表示“我需要一个随机访问集合,但我不需要能够修改它”。例如,一个BinarySearch方法可能如下所示:

public int BinarySearch<T>(IReadOnlyList<T> list, int start, int length);

为了使这个方法有用,它需要能够传入任何列表。强制创建包装器集合将非常昂贵。

于 2013-07-08T17:05:47.270 回答