假设我有一个类

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将创建一个新列表,但是因为在这种情况下MyObject是一个引用类型,所以新列表将包含对与原始列表相同对象的引用。

更新新列表中引用的对象的SimpleInt属性也会影响原始列表中的等效对象。

(如果MyObject声明为结构体而不是类,则新列表将包含原始列表中元素的副本,并且更新新列表中元素的属性不会影响原始列表中的等效元素。)

其他回答

从Reflector来源:

public static List<TSource> ToList<TSource>(this IEnumerable<TSource> source)
{
    if (source == null)
    {
        throw Error.ArgumentNull("source");
    }
    return new List<TSource>(source);
}

所以是的,你的原始列表不会被更新(即添加或删除),但引用的对象将。

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

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

是的,ToList将创建一个新列表,但是因为在这种情况下MyObject是一个引用类型,所以新列表将包含对与原始列表相同对象的引用。

更新新列表中引用的对象的SimpleInt属性也会影响原始列表中的等效对象。

(如果MyObject声明为结构体而不是类,则新列表将包含原始列表中元素的副本,并且更新新列表中元素的属性不会影响原始列表中的等效元素。)

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

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

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

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

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

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