是否Enumerable.Select()创建一个新对象并返回它
本文关键字:对象 新对象 返回 Select Enumerable 创建 是否 一个 | 更新日期: 2023-09-27 18:22:00
我正在使用Enumerable.Select()方法从现有列表中创建一个新的IEnumerable列表。以下是代码示例:
class ClassA
{
IEnumerable<TypeA> List1;
....
}
class ClassB
{
IEnumerable<TypeB> List2;
...
}
class TypeA
{
//some properties;
IEnumerable<TypeC> Prop3;
}
class TypeB
{
//some properties;
IEnumerable<TypeC> Property3;
}
.
.
.
.
ClassA input; //input data object
ClassB result = new classB();
result.List2 = input.List1.Select(s =>
{
new TypeB()
{
Property1 = s.Prop1,
Property2 = s.Prop2,
Property3 = s.Prop3==null?null:s.Prop3.Select(c=>c)
}
});
在上面的例子中,List2是List1的深层副本还是浅层副本?如果没有,我如何获得深度复制?
此外,如果我在上面的代码执行后(在创建结果对象后)设置Prop3=null,则结果。Property3也变为null。有人能解释为什么会发生这种情况吗?
对Select()的调用实际上并不会导致在使用点枚举s.Prop3,相反,您可以将其视为对s.Prop3的视图,以便稍后访问Property3时,它将在该点枚举s.Prop3。
如果要在将s.Prop3分配给Property3时复制其内容,请使用:
s.Prop3.ToList()
相反这会将s.Prop3逐元素复制到一个新列表中,这意味着如果稍后修改s.Prop3,它将不会对Property3产生影响。
在上面的例子中,List2是List1的深层副本还是浅层副本?
从技术上讲,两者都没有,因为IEnumerable还没有被枚举。这也适用于Property3
值。一旦列举出来,它似乎就是一个深度复制。
如果我在上面的代码执行后(在创建结果对象后)设置Prop3=null,则结果。Property3也变为null。
这是因为您可能在设置Prop3=null之后枚举result.List2
。这完全是基于对Select
实际作用的明显误解——它不是在执行行时创建新的集合,而是在调用ToList
、ToArray
、foreach(var x in y)
等时(即每当枚举时)如何创建这样的集合的说明。