public class TestClass
{
public int Num { get; set; }
public string Name { get; set; }
}
IEnumerable<TestClass> originalEnumerable
= Enumerable.Range(1, 1).
Select(x => new TestClass() { Num = x, Name = x.ToString() });
List<TestClass> listFromEnumerable = originalEnumerable.ToList();
// false
bool test = ReferenceEquals(listFromEnumerable[0], originalEnumerable.ElementAt(0));
Run Code Online (Sandbox Code Playgroud)
如果我修改复制的对象,原始文件不会更改.
我从中理解,System.Linq.IEnumerable<T>即使在调用ToList()/ 时它们是引用类型,集合也总是会生成新对象ToArray().我错过了一些东西,因为其他SO问题坚持只有复制参考.
Pet*_*ete 11
实际上,这是错误的原因是因为你的枚举实际上被枚举了两次,一次是在调用中originalEnumerable.ToList(),第二次是在你调用时originalEnumerable.ElementAt(0).
由于它枚举了两次,因此每次枚举时都会创建新对象.
你错过了这个事实,这Enumerable.Range是懒惰的,所以这一行实际上只产生内存中的查询定义:
IEnumerable<TestClass> originalEnumerable
= Enumerable.Range(1, 1).
Select(x => new TestClass() { Num = x, Name = x.ToString() });
Run Code Online (Sandbox Code Playgroud)
调用ToList()触发查询并使用新项创建列表:
List<TestClass> listFromEnumerable = originalEnumerable.ToList();
Run Code Online (Sandbox Code Playgroud)
在originalEnumerable.ElementAt(0)这里打电话
bool test = ReferenceEquals(listFromEnumerable[0], originalEnumerable.ElementAt(0));
Run Code Online (Sandbox Code Playgroud)
再次触发查询,并生成另一个新项目.
更新
所以你应该说,这Enumerable.Range会产生新的物品,而不是ToList().
如果您的源集合已经被评估(例如TestClass[]数组)ToList()将不会创建新项目:
IEnumerable<TestClass> originalEnumerable
= Enumerable.Range(1, 1).
Select(x => new TestClass() { Num = x, Name = x.ToString() })
.ToArray();
List<TestClass> listFromEnumerable = originalEnumerable.ToList();
// true
bool test = ReferenceEquals(listFromEnumerable[0], originalEnumerable[0]);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
725 次 |
| 最近记录: |