C#数组值在函数中意外更改

时间:2013-09-23 09:58:16

标签: c# arrays

我不明白为什么当我更改“copy_of_digits”数组时,“digits”和“parse_result”数组也会发生变化?我检查了一些关于通过引用传递和传递值的在线帮助,并且在那里写了C#传递值是默认值,并且您必须使用“ref”通过引用传递。我认为这里发生的是数组是通过引用传递的,而不是通过值传递的,但我不明白为什么以及如何解决它。任何帮助,将不胜感激!

namespace TestWithArrays
    {
        class Program
        {
            public static void Main()
            {
                Console.WriteLine("Please enter 2 digits:");
                string user_input = Console.ReadLine();
                int[] parse_result = Parse(user_input);
                int[] multiply_by_two_result = MultiplyByTwo(parse_result);
                Console.WriteLine("The End...");
                Console.ReadLine();
            }
            public static int[] Parse(string user_input)
            {
                int[] digits = new int [2];
                digits[0] = Int32.Parse(user_input.Substring(0,1));
                digits[1] = Int32.Parse(user_input.Substring(1,1));
                return digits;
            }
            public static int[] MultiplyByTwo(int[] digits)
            {
                int[] copy_of_digits = new int [2];
                copy_of_digits = digits;
                Console.WriteLine("´digits´ array before copy has been modified: " + string.Join(string.Empty, digits));
                copy_of_digits[0] = copy_of_digits[0] * 2;
                copy_of_digits[1] = copy_of_digits[1] * 2 ;
                Console.WriteLine("´digits´ array after copy has been modified: " + string.Join(string.Empty, digits));
                Console.WriteLine("´parse_result´ after copy has been modified: " + string.Join(string.Empty, digits));
                return copy_of_digits;
            }
        }
    }

4 个答案:

答案 0 :(得分:6)

而不是分配引用

copy_of_digits = digits;

将所有从digits数组复制到copy-of_digites数组:

Array.Copy(digits, copy_of_digits, 2);

否则,您将有几个引用指向内存中的相同项目。

答案 1 :(得分:1)

是的,C#默认为传递值;但你需要注意你通过值传递的:在这里,你按值传递引用。引用基本上是数组的地址。无论您是更改digits[0] = ...,还是将digits分配给其他变量,然后更改copy_of_digits[0] = ...,您仍然在更改相同的数组。重要的是,在这里:

int[] copy_of_digits = new int [2];
copy_of_digits = digits;

第一个new int [2]数组完全放弃在这里 - 它没有用处。第二行不复制数组 - 它只复制引用并将其分配给另一个变量。

基本上,如果我们忽略了多余的new int [2] - 您的问题中只有只有1个数组。很自然地,无论我们在哪里或如何我们改变了内容,这些变化随处可见:毕竟,它是所有相同的数组。

我怀疑你实际想要做的是:

public static int[] MultiplyByTwo(int[] digits)
{
    int[] copy_of_digits = (int[])digits.Clone();
    ...

答案 2 :(得分:0)

  

在那里写的是在C#中传递值是默认的,你必须使用“ref”来通过引用传递。

这是正确的,但是通过值传递的东西是引用本身(因为数组是.NET中的引用类型)。

这就是你必须复制阵列的原因。如果只是一个引用类型对象数组,则必须复制所有数组项。

答案 3 :(得分:0)

ref用于传递对变量的引用。这意味着变量所持有的参考/值也可以改变。

现在变量持有的值可以是引用类型或值类型(http://msdn.microsoft.com/en-us/library/t63sy5hs.aspx)。在值类型的情况下,例如int / struct,传递值的副本,而对于引用类型,您仍然可以获得对原始对象的引用(在您的情况下,引用原始数组),因此更改成员会更改原始对象的成员。 / p>