ToReadOnlyCollection扩展方法使用快捷语句实现,如果它已经是ReadOnlyCollection的实例,则直接返回输入。 ToList扩展方法不是。
纯粹出于好奇,有一个特殊的原因,或者只是发生了一些没有实施的事情。我可以理解为什么保证ToList
将始终返回一个新实例可能会有用,但是有兴趣知道是否还有其他任何原因。
答案 0 :(得分:11)
无法修改只读集合,因此根据.ToReadOnlyCollection()
返回相同的实例是完全可以接受的。
如果.ToList()
操作的结果有时会返回一个新列表,有时则不会在更改输出列表时知道是否修改了源列表。因此,.ToList()
总是返回一个新实例。
答案 1 :(得分:2)
这是合理的。由于您可能会在此过程中稍后更改List<T>
,因此您需要对原始List<T>
进行复制。
您可以考虑推迟流程,直到您更改已创建列表的值。但请注意,您可能会先更改第一个列表。
示例:
List<String> first = new List<String>(new string[] {"foo","bar"});
List<String> second = first.ToList();
first[0] = "qux";
现在要确保在更改列表之前复制是非常困难的。此外,由于每次更新值时效率较低,因此应首先检查是否存在惰性副本,并且在这种情况下开始复制。此外,它可能导致爆发/泡沫:在修改单个值之后最终要执行的大量工作可能导致巨大的延迟。想象一下,你正在运行一个服务器,人们可以在这里使用#&fork;#34;热门的名单。最终该列表确实被修改了。这可能导致用户等待几分钟,因为服务器开始为首先分配该列表的所有人制作副本。随着时间的推移扩展计算会更好,因此延迟方差较小。
.ToReadOnlyCollection
的情况不同。在这种情况下,您在原始列表周围定义一个包装器。如果您修改原始列表,该更改也会反映在只读集合中。所以你可以链接到上一个列表。例如:
$ csharp
Mono C# Shell, type "help;" for help
Enter statements below.
csharp> List<String> first = new List<String>(new string[] {"foo","bar"});
csharp> var sec = first.AsReadOnly();
csharp> sec
{ "foo", "bar" }
csharp> first[0] = "qux";
csharp> sec
{ "qux", "bar" }