没有out或ref的方法如何在外部改变变量?C#

Jo *_*Smo 0 c# pass-by-reference pass-by-value

如何a从SumElemtnts方法内部更改数组的值?是因为它是静态方法吗?因为该方法仅返回变量,sum并且没有ref或out.

class Program
{
    public static int SumElements(int[] a)
    {
        int[] a2 = a;
        int sum = 0;
        for (int i = 0; i < a2.Length; i++)
        {
            int temp = a2[i] * 10;
            a2[i] = temp;
            sum += temp;
        }
        a[a2.Length - 2] = sum;
        return sum;
    }

    public static void Main(string[] args)
    {
        int[] a = { 1, 2, 3 };
        int sum = SumElements(a);

        Console.Write("Sum = " + sum + ", ");
        for (int i = 0; i < a.Length; i++)
        {
            Console.Write(a[i] + " ");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

结果是:

总和= 60,10 60 30

Jon*_*eet 6

你没有改变变量的值SumElements- 它仍然引用它之前所做的相同数组.请注意a该SumElements方法中没有赋值.

相反,您正在更改数组的内容.这种变化在内部是可见的Main,因为它仍然具有对数组的引用.

把变量想象成一张纸.在Main,你有一个名为的变量a,它包含一个引用 - 一种获取数组的方法.这就像有一张带有街道地址的纸.那是房子的街道地址 - 类似于数组对象.

您复制该值(街道地址),并把它作为价值a在SumElements.这两张纸是分开的 - 你可以在上面涂抹SumElements一张纸而不会改变纸张Main- 但是它们从相同的街道地址开始.SumElements然后去那个街道地址,然后画一个窗户.当然Main后去同一个街道地址时,它也会看到绘制的窗口......因为只有一个房子(数组对象),即使有两张纸上写着相同的街道地址.

有关详细信息,请参阅有关参数传递和引用类型以及值类型的文章.


ang*_*son 5

数组是一种引用类型。

您不是传入数组的副本,而是传入对它的引用。

这是一个较小的LINQPad程序,用于演示:

void Main()
{
    var a = new[] { 1, 2, 3 };
    Test(a);
    a.Dump();
}

public static void Test(int[] arr)
{
    arr[1] = 15;
}
Run Code Online (Sandbox Code Playgroud)

输出:

1
15
3
Run Code Online (Sandbox Code Playgroud)

更长的描述:当您将值传递给 C# 中的方法时,默认情况下它是“按值传递”,这意味着您传递的是值的副本,而不是实际变量本身。

在这种情况下,您传入的是引用的副本,但引用引用的是一个数组。

因此,该方法有自己对数组的引用,但它仍然使用与“外部”代码相同的数组。