出于好奇,为什么在现有List上调用IEnumerable.ToList()不会返回相同的实例?同样适用于IEnuerable.ToArray()。从内存消耗的角度来看,这会不会更好?
我进行了以下快速测试:
var things= new List<Thing>( new [] {new Thing(), new Thing()});
Console.WriteLine(things.GetHashCode());
things= things.ToList();
Console.WriteLine(things.GetHashCode());
我得到了不同的对象实例。为什么不是简单的相同实例?
答案 0 :(得分:9)
这是故意这样做以启用“复制列表”方案。
例如,我做foreach( var a in list ) list.Remove(a)
,我会在枚举进行过程中得到一个例外,说明“该集合已被修改”。
要解决此问题,请执行:foreach( var a in list.ToList() ) list.Remove(a)
。
如果你想要“转换为列表,如果它不是已经存在”的语义,你将不得不自己处理它。实际上,您实际上可以为此编写一个简洁的扩展方法:
public static IList<T> ToListIfNotAlready( this IEnumerable<T> source )
{
var list = source as IList<T>;
return list == null ? source.ToList() : list;
}
是的,它可能是另一种方式,但LINQ设计师选择了这种方法,并且完全有权这样做,因为在一般情况下这两种方法都没有明显的优势。
答案 1 :(得分:1)
由于在枚举枚举时无法修改枚举的内容,因此有时需要创建列表副本,以便迭代一个副本并修改另一个副本。 ToList()定义为返回 new 列表,该列表独立于原始列表。
答案 2 :(得分:0)
ToList()的行为与枚举无关。它完成了名称所暗示的,即它返回一个列表。它并不意味着每次调用都返回相同的列表;除此以外;列表实例必须存储在内部某处。与许多其他Linq功能相同。它返回一个新列表这一事实有利于与foreach枚举器一起使用。