【问题标题】:Does C# ToList() method really make a shadow copy? [duplicate]C# ToList() 方法真的会创建卷影副本吗? [复制]
【发布时间】:2021-09-29 03:41:12
【问题描述】:

根据以下链接,调用ToList()方法时会做一个shadow copy。

https://forums.asp.net/t/1638787.aspx?Does+ToList+create+a+shallow+or+deep+copy+of+an+existing+List+collection+

我已经测试了一些案例,但是我发现了一些奇怪的东西。

  1. 案例 - 自定义类 => 结果与上述结论相符。如果我更改了一个列表中对象的属性,而另一个也更改了。

  2. 大小写 - 字符串 => 结果与上述结论相矛盾。我已经更改了一个列表中的字符串,但另一个列表的值仍然与以前相同。

在我看来,Custom Class 和 String 都是对象,有什么区别呢? 任何人都可以建议吗?非常感谢!

var originalList1 = new List<Person> { new Person { Name = "Apple" }, new Person { Name = "Banana" } };
var copyList1 = originalList1.ToList();

originalList1[0].Name = "Orange";

Console.WriteLine(originalList1[0].Name);   // Orange
Console.WriteLine(copyList1[0].Name);       // Orange    


var originalList2 = new List<string> { "Apple", "Banana" };
var copyList2 = originalList2.ToList();

originalList2[0] = "Orange";
Console.WriteLine(originalList2[0]);        // Orange
Console.WriteLine(copyList2[0]);            // Apple  --- Why?

【问题讨论】:

  • 提示:字符串是不可变的。如果不只是更改originalList1[0].Name = ...,而是分配一个像originalList1[0] = ... 这样的Person 对象,会发生什么?
  • 修改一个对象的一个​​实例,和用一个不同的对象实例的引用替换一个对象实例的引用是有区别的。您不能修改string,因为它是不可变的,因此在这种情况下,您将替换引用,而不是修改对象本身,因此观察到的行为会有所不同。查看副本。
  • 让我们将苹果与苹果进行比较,而不是香蕉或人:originalList1[0] = new Person{ Name = "Orange"} - 现在它们的行为相同(都打印 Orange 然后 Apple) - 您的“为什么”的答案由此形成
  • 抱歉这个愚蠢的问题。字符串是不可变的,这意味着我替换了一个新的而不是更改它的值。

标签: c# linq tolist


【解决方案1】:

你不能“改变”一个字符串——字符串是不可变的。您将替换原始列表中位置0 的字符串用新字符串。这不会影响另一个列表的索引 0 处的字符串。

List&lt;Person&gt; 的情况下,列表包含对象的引用。复制列表时 - references 被复制,但它们指向相同的对象,因此替换其中一个对象的属性会反映在两个列表中。

【讨论】:

    猜你喜欢
    • 2010-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 2011-04-27
    • 2016-02-21
    • 2015-02-08
    相关资源
    最近更新 更多