假设我有一个类
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:很抱歉,这似乎是显而易见的。但是我现在没有编译器……
接受的答案根据OP的例子正确地回答了他的问题。但是,它只适用于将ToList应用于具体集合时;当源序列的元素还没有被实例化(由于延迟执行)时,它不会保持。对于后一种情况,每次调用ToList(或枚举序列)时可能会得到一组新的项。
下面是OP代码的改编,以演示这种行为:
public static void RunChangeList()
{
var objs = Enumerable.Range(0, 10).Select(_ => new MyObject() { SimpleInt = 0 });
var whatInt = ChangeToList(objs); // whatInt gets 0
}
public static int ChangeToList(IEnumerable<MyObject> objects)
{
var objectList = objects.ToList();
objectList.First().SimpleInt = 5;
return objects.First().SimpleInt;
}
虽然上面的代码可能看起来不自然,但在其他情况下,这种行为可能是一种微妙的错误。请参阅我的另一个示例,了解它导致重复生成任务的情况。
只是偶然发现了这个旧帖子,并想补充我的意见。通常,如果我有疑问,我会快速地在任何对象上使用GetHashCode()方法来检查标识。对于上面的-
public class MyObject
{
public int SimpleInt { get; set; }
}
class Program
{
public static void RunChangeList()
{
var objs = new List<MyObject>() { new MyObject() { SimpleInt = 0 } };
Console.WriteLine("objs: {0}", objs.GetHashCode());
Console.WriteLine("objs[0]: {0}", objs[0].GetHashCode());
var whatInt = ChangeToList(objs);
Console.WriteLine("whatInt: {0}", whatInt.GetHashCode());
}
public static int ChangeToList(List<MyObject> objects)
{
Console.WriteLine("objects: {0}", objects.GetHashCode());
Console.WriteLine("objects[0]: {0}", objects[0].GetHashCode());
var objectList = objects.ToList();
Console.WriteLine("objectList: {0}", objectList.GetHashCode());
Console.WriteLine("objectList[0]: {0}", objectList[0].GetHashCode());
objectList[0].SimpleInt = 5;
return objects[0].SimpleInt;
}
private static void Main(string[] args)
{
RunChangeList();
Console.ReadLine();
}
然后在答录机上回答
obj: 45653674
obj [0]: 41149443
对象:45653674
对象[0]:41149443
objectList: 39785641
objectList [0]: 41149443
whatInt: 5
所以本质上list所携带的对象在上面的代码中保持不变。希望这种方法能有所帮助。