2

我不明白为什么当我更改“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

4 回答 4

7

而不是分配参考

copy_of_digits = digits;

将数字数组中的所有复制到 copy-of_digites 数组:

Array.Copy(digits, copy_of_digits, 2);

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

于 2013-09-23T10:00:15.007 回答
1

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

没错,但是按值传递的东西是引用本身(因为数组是 .NET 中的引用类型)。

这就是为什么你必须复制你的数组。如果只是引用类型对象的数组,则必须复制所有数组项。

于 2013-09-23T10:02:27.010 回答
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();
    ...
于 2013-09-23T10:02:52.053 回答
0

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

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

于 2013-09-23T10:08:04.450 回答