我正在使用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(在创建结果对象之后),则result.Property3也变为null。有人可以解释为什么会这样吗?
答案 0 :(得分:2)
对Select()的调用实际上并不会导致s.Prop3在其使用的位置被枚举,而是你可以把它想象成s.Prop3的视图,这样以后,当你访问Property3时,它会此时枚举s.Prop3。
如果要在将s.Prop3分配给Property3时复制其内容,请使用:
s.Prop3.ToList()
...来代替。这会将s.Prop3(逐个元素)复制到一个新列表中,这意味着如果稍后修改s.Prop3,它将对Property3没有影响。
答案 1 :(得分:1)
在上面的示例中,List2会是List1的深层副本还是浅层副本?
从技术上讲,既不是因为没有枚举IEnumerable。这也适用于Property3
值。枚举后,它似乎是一个深层副本。
如果我在上面的代码执行后设置Prop3 = null(创建结果对象后),result.Property3也会变为空。
这是因为您可能在设置Prop3 = null后枚举result.List2
。这完全基于对Select
实际所做的明显误解 - 它不会在执行行时创建新的集合,而是指示如何在ToList
,ToArray
,foreach(var x in y)
等被调用时(即,无论何时枚举)都会创建此类集合。