【问题标题】:In C#, when I set a new list equal to another list, does it set the new list as a pointer to the other list or is it actually creating a new list?在 C# 中,当我将新列表设置为等于另一个列表时,它是将新列表设置为指向另一个列表的指针还是实际上创建了一个新列表?
【发布时间】:2013-09-05 18:45:01
【问题描述】:

当我设置一个新列表等于另一个列表时,它是将新列表设置为指向另一个列表的指针还是实际上创建了一个新列表?

例如,

是……

List<SomeType> newList = oldList;

...与...相同

List<SomeType> newList = new List<SomeType>();
newList.AddRange(oldList);

(oldList 也是 SomeType 的列表)?

【问题讨论】:

  • 也很容易通过实验弄清楚...
  • 是的,但是我在哪里可以找到以这种方式运行的所有数据类型的列表?我想这就是我更感兴趣的……
  • 几乎所有 C#(或大多数语言)中的赋值都很浅。你问的是深拷贝。默认情况下这样做会大大减慢速度,并导致一些非常意外的行为。 (编辑:是的,C++ 中有很好的 ol' 复制构造函数,以及按值复制的参数传递,但我们不要把它复杂化)。
  • 我对这个主题的先例回答stackoverflow.com/questions/18625553/…
  • @Alexandru 所有引用类型都以这种方式运行。赋值运算符复制所有值类型(以及它们各自的值,递归地,但复制值类型中包含的引用,而不是引用的对象)。

标签: c# list object pointers


【解决方案1】:

将有一个List 和多个对其的引用。这适用于所有引用类型(类)。

另一方面,值类型(结构)在分配时被复制。

【讨论】:

  • Theodoros,我在哪里可以找到 C# 中所有内置引用类型的列表?编辑:也许,最好只找到 C# 中所有值类型的列表,因为它更小,然后考虑所有其他类型的引用类型?
  • @Alexandru 要以编程方式确定它,有Type.IsStruct。要在编写代码时确定它,请在 IDE 中查找提示(例如,据我所知,VS 对结构有不同的 IntelliSense 图标)。如果由于任何原因无法做到这一点,请检查您当时正在使用的库的文档。
  • 很好的答案,伙计。感谢您尊重这个问题并深入探讨这个问题。
【解决方案2】:

赋值运算符不是克隆运算符。对于引用类型,它会复制引用的值。

【讨论】:

    【解决方案3】:

    在分配中像:

    List<SomeType> newList = oldList;
    

    两个列表将完全相同,在列表中添加或删除一个项目将使其在另一个列表中发生变化。除了额外的指针之外,它们都使用相同的内存空间。

    List<SomeType> newList = new List<SomeType>();
    newList.AddRange(oldList);
    

    将是 2 个独立的列表(都在内存中)。一个列表中的更改不会影响另一个列表。

    请记住,如果您的“SomeType”是一个复杂的类型......让我们说一个“产品”。在这两种情况下,所有列表都将引用您的产品,因此对产品的更改将在另一个列表中更改。

    要复制列表和产品,您需要克隆产品,这可能会造成欺骗,因为克隆是递归的,具体取决于类型的复杂性。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-01
      • 2011-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-13
      • 1970-01-01
      相关资源
      最近更新 更多