C#:更改数组副本会更改数组本身

时间:2018-04-28 21:15:42

标签: c# arrays

我在C#中有一个非常基本的问题。所以我有一个名为m_permutation(类的属性)的int数组,并且在类的方法中我有以下代码:

    int[] newPermutation = new int[m_permutation.Length];
    newPermutation = m_permutation;
    newPermutation[0] = 5;

我很困惑为什么m_permutation在这段代码中也被更改了,我该如何解决?

我知道我可以通过循环初始化newPermutation,以获得相同的m_permutation值,并修复它。但是,有人可以解释为什么会发生这种情况,最好的解决办法是什么?

谢谢,

的Bogdan

2 个答案:

答案 0 :(得分:5)

对于您对代码的期望,有一些好处,有些不好。

让我们了解您的代码实际执行的操作:

int[] newPermutation = new int[m_permutation.Length];

这将声明一个新变量newPermutation为一个int数组,然后构造一个包含m_permutation.Length元素的新int数组。

到目前为止一切顺利。

下一行,不是那么多:

newPermutation = m_permutation;

这一行实际上会替换数组变量newPermutation中的引用,在赋值后,引用与m_permutation相同的数组。

让我们考虑一下数组变量究竟是什么。

执行此操作时:

int[] x = new int[5];

然后你做了几件事:

  1. 您正在声明变量x
  2. 您正在构建包含int数组
  3. 的新对象
  4. 您正在分配变量x以引用此对象
  5. 第二行之后:

    newPermutation = m_permutation;
    

    你基本上是这样说的:

    1. 好的,你知道我们刚构建的数组吗?忘记了
    2. 现在让我们引用另一个数组,即变量m_permutation也指的数组。
    3. 所以当这一行执行时:

      newPermutation[0] = 5;
      

      你实际上是在说:newPermutation现在引用的数组,它的第一个元素现在应该具有值5.

      由于此时newPermutation引用与m_permutation相同的数组,因此您似乎正在修改其他数组,但实际上您只有一个数组。但是,您有两个引用相同数组的变量。

      我建议你阅读关于指针的答案here,因为这是相关的。

      但是,您可以轻松解决问题。

      您可以要求提供数组的副本,而不是对原始数据的引用。

      只需将您的代码更改为:

      int[] newPermutation = m_permutation.ToArray();
      

      .ToArray()方法保证返回 new 数组,因此不会与原始数据共享。

      但请记住,如果使用比int更复杂的东西(例如对象)执行此操作,则只能获取对象引用的副本,而不是对象的副本他们自己。如果到达这一点,您可以在回答Stack Overflow时遇到新问题。

答案 1 :(得分:1)

因为它们都在内存中引用相同的对象。 你可以用,

Array.Copy(m_permutation, newPermutation,m_permutation.Length );