假设我有一个类

public class MyObject
{
   public int SimpleInt{get;set;}
}

我有一个List<MyObject>,我ToList()它,然后改变一个SimpleInt,我的改变会被传播回原来的列表。换句话说,下面这个方法的输出是什么?

public void RunChangeList()
{
  var objs = new List<MyObject>(){new MyObject(){SimpleInt=0}};
  var whatInt = ChangeToList(objs );
}
public int ChangeToList(List<MyObject> objects)
{
  var objectList = objects.ToList();
  objectList[0].SimpleInt=5;
  return objects[0].SimpleInt;

}

为什么?

P/S:很抱歉,这似乎是显而易见的。但是我现在没有编译器……


当前回答

我认为这相当于问ToList是做深度复制还是浅复制。由于ToList无法克隆MyObject,它必须进行浅拷贝,因此创建的列表包含与原始列表相同的引用,因此代码返回5。

其他回答

ToList将始终创建一个新列表,该列表不会反映对集合的任何后续更改。

但是,它会反映对象本身的变化(除非它们是可变结构体)。

换句话说,如果用不同的对象替换原始列表中的对象,ToList仍将包含第一个对象。 但是,如果修改了原始列表中的一个对象,ToList仍将包含相同的(修改后的)对象。

创建一个新列表,但其中的项是对原始项的引用(就像在原始列表中一样)。对列表本身的更改是独立的,但对项目的更改将发现两个列表中的更改。

是的,它创建了一个新列表。这是有意为之。

该列表将包含与原始可枚举序列相同的结果,但将其具体化为一个持久(内存中)集合。这允许您多次使用结果,而不会产生重新计算序列的成本。

LINQ序列的美妙之处在于它们是可组合的。通常,您得到的IEnumerable<T>是组合多个过滤、排序和/或投影操作的结果。像ToList()和ToArray()这样的扩展方法允许您将计算序列转换为标准集合。

ToList将创建一个全新的列表。

如果列表中的项是值类型,它们将被直接更新,如果它们是引用类型,任何更改都将反映回被引用的对象中。

如果源对象是一个真正的IEnumerable(即不仅仅是一个打包为enumerable的集合),ToList()可能不会返回与原始IEnumerable中相同的对象引用。它将返回一个新的对象列表,但这些对象可能与IEnumerable再次枚举时产生的对象不相同,甚至不相等