如果输入已经是列表,则ToList不会快捷方式

时间:2015-02-23 11:37:50

标签: c# linq

ToReadOnlyCollection扩展方法使用快捷语句实现,如果它已经是ReadOnlyCollection的实例,则直接返回输入。 ToList扩展方法不是。

纯粹出于好奇,有一个特殊的原因,或者只是发生了一些没有实施的事情。我可以理解为什么保证ToList将始终返回一个新实例可能会有用,但是有兴趣知道是否还有其他任何原因。

2 个答案:

答案 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" }