ToList()— Does it Create a New List?

2019-01-02 17:55发布

Let's say I have a class

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

And I have a List<MyObject>, and I ToList() it and then change one of the SimpleInt, will my change be propagated back to the original list. In other words, what would be the output of the following method?

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;

}

Why?

P/S: I'm sorry if it seems obvious to find out. But I don't have compiler with me now...

标签: c# linq
12条回答
骚的不知所云
2楼-- · 2019-01-02 17:59

I think that this is equivalent to asking if ToList does a deep or shallow copy. As ToList has no way to clone MyObject, it must do a shallow copy, so the created list contains the same references as the original one, so the code returns 5.

查看更多
裙下三千臣
3楼-- · 2019-01-02 18:00

From the Reflector'd source:

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

So yes, your original list won't be updated (i.e. additions or removals) however the referenced objects will.

查看更多
无色无味的生活
4楼-- · 2019-01-02 18:03
 var objectList = objects.ToList();
  objectList[0].SimpleInt=5;

This will update the original object as well. The new list will contain references to the objects contained within it, just like the original list. You can change the elements either and the update will be reflected in the other.

Now if you update a list (adding or deleting an item) that will not be reflected in the other list.

查看更多
临风纵饮
5楼-- · 2019-01-02 18:05

I don't see anywhere in the documentation that ToList() is always guaranteed to return a new list. If an IEnumerable is a List, it may be more efficient to check for this and simply return the same List.

The worry is that sometimes you may want to be absolutely sure that the returned List is != to the original List. Because Microsoft doesn't document that ToList will return a new List, we can't be sure (unless someone found that documentation). It could also change in the future, even if it works now.

new List(IEnumerable enumerablestuff) is guaranteed to return a new List. I would use this instead.

查看更多
孤独寂梦人
6楼-- · 2019-01-02 18:06

A new list is created but the items in it are references to the orginal items (just like in the original list). Changes to the list itself are independent, but to the items will find the change in both lists.

查看更多
人气声优
7楼-- · 2019-01-02 18:07

Yes, ToList will create a new list, but because in this case MyObject is a reference type then the new list will contain references to the same objects as the original list.

Updating the SimpleInt property of an object referenced in the new list will also affect the equivalent object in the original list.

(If MyObject was declared as a struct rather than a class then the new list would contain copies of the elements in the original list, and updating a property of an element in the new list would not affect the equivalent element in the original list.)

查看更多
登录 后发表回答