假设我有一个类

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将创建一个全新的列表。

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

其他回答

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

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

 var objectList = objects.ToList();
  objectList[0].SimpleInt=5;

这也将更新原始对象。新列表将包含对其中包含的对象的引用,就像原始列表一样。您可以更改其中一个元素,更新将反映在另一个元素中。

现在,如果你更新一个列表(添加或删除一个项目),将不会反映在另一个列表。

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

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

我在文档中没有看到ToList()总是保证返回一个新列表。如果IEnumerable是一个List,检查它并返回相同的List可能会更有效。

令人担心的是,有时您可能希望绝对确保返回的List是原来List的!=。因为微软没有记录ToList将返回一个新的List,所以我们不能确定(除非有人找到了该文档)。即使现在可行,未来也可能发生变化。

new List(IEnumerable enumerablestuff)保证返回一个新的List。我会用这个代替。