C# 通过值和引用传递数组

C# 通过值和引用传递数组,c#,arrays,C#,Arrays,这些都是我正在阅读的一本c#书中的一个例子,只是在理解这个例子实际上在做什么时有点困难。我想通过一个解释来帮助我进一步理解这里发生的事情 //creates and initialzes firstArray int[] firstArray = { 1, 2, 3 }; //Copy the reference in variable firstArray and assign it to firstarraycopy int[

这些都是我正在阅读的一本c#书中的一个例子,只是在理解这个例子实际上在做什么时有点困难。我想通过一个解释来帮助我进一步理解这里发生的事情

        //creates and initialzes firstArray
        int[] firstArray = { 1, 2, 3 };

        //Copy the reference in variable firstArray and assign it to firstarraycopy
        int[] firstArrayCopy = firstArray;

        Console.WriteLine("Test passing firstArray reference by value");


        Console.Write("\nContents of firstArray " +
            "Before calling FirstDouble:\n\t");

        //display contents of firstArray with forloop using counter
        for (int i = 0; i < firstArray.Length; i++)
            Console.Write("{0} ", firstArray[i]);

        //pass variable firstArray by value to FirstDouble
        FirstDouble(firstArray);

        Console.Write("\n\nContents of firstArray after " +
            "calling FirstDouble\n\t");

        //display contents of firstArray
        for (int i = 0; i < firstArray.Length; i++)
            Console.Write("{0} ", firstArray[i]); 

        // test whether reference was changed by FirstDouble
        if (firstArray == firstArrayCopy)
            Console.WriteLine(
                "\n\nThe references refer to the same array");
        else
            Console.WriteLine(
                "\n\nThe references refer to different arrays");

       //method firstdouble with a parameter array
       public static void FirstDouble(int[] array)
    {
        //double each elements value
        for (int i = 0; i < array.Length; i++)
            array[i] *= 2;

        //create new object and assign its reference to array
        array = new int[] { 11, 12, 13 };
//创建并初始化firstArray
int[]firstArray={1,2,3};
//复制变量firstArray中的引用并将其分配给firstarraycopy
int[]firstArrayCopy=firstArray;
WriteLine(“通过值传递firstArray引用的测试”);
控制台。写入(“\n第一个数组的内容”+
“在调用FirstDouble之前:\n\t”);
//使用计数器显示forloop的firstArray的内容
for(int i=0;i
基本上有一段代码,我想知道的是,书中说,如果数组是按值传递的,那么原始调用方不会被方法修改(据我所知)因此,在方法FirstDouble的末尾,他们尝试将局部变量数组分配给一组失败的新元素,当显示时,原始调用者的新值为2,4,6

现在我的困惑是,如果通过值传递,方法FirstDouble中的for循环如何将原始调用方firstArray修改为2,4,6。我认为值应该保持为1,2,3


提前感谢

理解这一点的关键是要知道两种语言之间的区别

例如,考虑一个典型的值类型,<代码> int < /代码> .<

int a = 1;
int b = a;
a++;
执行此代码后,
a
的值为2,
b
的值为
1
。因为
int
是一种值类型,
b=a
复制
a
的值

现在考虑一个类:

MyClass a = new MyClass();
a.MyProperty = 1;
MyClass b = a;
a.MyProperty = 2;
因为类是引用类型,
b=a
只分配引用而不是值。所以
b
a
都引用同一个对象。因此,在执行
a.MyProperty=2
之后,
b.MyProperty==2
因为
a
b
引用同一个对象


考虑到您问题中的代码,数组是一种引用类型,因此对于此函数:

public static void FirstDouble(int[] array)
public static void FirstDouble(int[] array)
{
    //double each elements value
    for (int i = 0; i < array.Length; i++)
        array[i] *= 2;

    //create new object and assign its reference to array
    array = new int[] { 11, 12, 13 };
}
变量
array
实际上是一个引用,因为
int[]
是一个引用类型。因此
array
是一个按值传递的引用

因此,在函数中对
数组
所做的修改实际上应用于
数组
所引用的
int[]
对象。因此这些修改对引用同一对象的所有引用都是可见的。这包括调用者持有的引用

现在,如果我们看一下此功能的实现:

public static void FirstDouble(int[] array)
public static void FirstDouble(int[] array)
{
    //double each elements value
    for (int i = 0; i < array.Length; i++)
        array[i] *= 2;

    //create new object and assign its reference to array
    array = new int[] { 11, 12, 13 };
}

然后引用
数组
将按引用传递,调用方将在函数返回时看到新创建的对象
{11,12,13}

所有方法参数都按值传递,除非您特别看到
ref
out

数组是引用类型。这意味着您正在按值传递引用


引用本身只有在为其分配新数组时才会更改,这就是为什么这些分配不会反映在调用者中。当您取消引用对象(此处的数组)并修改基础值时,您不会更改变量,只是更改它指向的值。此更改将被“看到”即使变量(即它指向的对象)保持不变,调用者也会这样做。

多么令人困惑的术语用法

澄清一下,

  • 对于方法
    foo(int[]myArray)
    ,“通过值传递引用(对象)”实际上意味着“传递对象地址(引用)的副本”。此“副本”(即
    myArray
    )的值最初是地址(引用)原始对象的属性,这意味着它指向原始对象。因此,
    myArray
    指向的内容的任何更改都将影响原始对象的内容

    但是,由于
    myArray
    本身的“值”是一个副本,因此对该“值”的任何更改都不会影响原始对象及其内容

  • 对于方法
    foo(ref int[]refArray)
    ,“通过引用传递引用(对象)”意味着“传递对象的地址(引用)本身(而不是副本)”。这意味着
    refArray
    实际上是对象本身的原始地址,而不是副本。因此,
    refArray
    的“值”或
    refArray
    指向的内容的任何更改都是对原始对象本身的直接更改


  • 这是一个为大家提供.net开源知识以实现逻辑的想法

    //Sample Code, Illustration;
    Method1(params dynamic[] var1) {
      var1[0]=new dynamic[3] { 1,2,3 }
    }
    
    var1未指定或不能为ref? 一个使用场景是

    //Sample Code, Illustration;
    dynamic[] test = new dynamic[];
    Method1( ref test,x,x,x,x  );
    System.Windows.MessageBox.Show( test[2].ToString() );
    
    仅在非特定参数时指示ref; 以及对数组项的引用

    //result is IndexOutOfBounds;
    
    这只是一个示例,可以通过返回数组和
    Method1( ref test,... );