0

我正在使用 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。有人可以解释为什么会这样吗?

4

2 回答 2

2

对 Select() 的调用实际上不会导致 s.Prop3 在使用时被枚举,而是您可以将其视为 s.Prop3 的视图,以便稍后访问 Property3 时,它将枚举 s。那时的 Prop3。

如果要在将 s.Prop3 分配给 Property3 时复制其内容,请使用:

 s.Prop3.ToList() 

...反而。这会将 s.Prop3 逐个元素地复制到一个新列表中,这意味着如果稍后修改 s.Prop3,它将对 Property3 没有影响。

于 2013-07-10T15:08:18.427 回答
1

在上面的例子中,List2 是 List1 的深拷贝还是浅拷贝?

技术上两者都不是,因为 IEnumerable 尚未被枚举。这也适用于该Property3值。一旦枚举,它似乎将是一个深层副本。

如果我在执行上述代码之后(在创建结果对象之后)设置 Prop3 = null,则 result.Property3 也变为 null。

这是因为您可能result.List2在设置 Prop3 = null 后进行枚举。这完全是基于对Select 实际操作的明显误解——它不会在执行行时创建新集合,而是关于如何在调用 、 、 等时创建这样一个集合的说明ToListToArrayforeach(var x in y),无论何时枚举)。

于 2013-07-10T15:17:16.057 回答