Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 没有out或ref的方法如何更改自身外部的变量?C_C#_Pass By Reference_Pass By Value - Fatal编程技术网

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

C# 没有out或ref的方法如何更改自身外部的变量?C,c#,pass-by-reference,pass-by-value,C#,Pass By Reference,Pass By Value,如何从SumElemtnts方法内部更改数组a的值?是因为它是静态方法吗?因为该方法只返回变量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 = a

如何从SumElemtnts方法内部更改数组a的值?是因为它是静态方法吗?因为该方法只返回变量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] + " ");
        }
    }
}
结果是:


Sum=60,106030

您没有更改SumElements中变量的值-它仍然引用以前使用的相同数组。请注意,在SumElements方法中没有对a的赋值

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

把一个变量想象成一张纸。大体上,您有一个名为a的变量,它包含一个引用—一种访问数组的方法。这就像有一张写着街道地址的纸。这是房屋的街道地址-类似于数组对象

您正在将该值复制到street address,并将其用作元素中a的值。这两张纸是分开的——你可以在SumElements中的那张纸上乱涂乱画,这不会改变这张纸的主要内容——但它们的起始地址是相同的。Summelements随后将前往该街道地址,并粉刷其中一扇窗户。当Main走到同一个街道地址时,它也看到了画好的窗户。。。因为数组对象中只有一个房子,即使上面有两张写有相同街道地址的纸


有关更多详细信息,请参阅我在和上的文章。

原因很简单,因为数组是引用类型,所以您正在更改数组的内容

从MSDN:

下面的示例演示如何通过值将引用类型参数arr传递给方法Change。由于该参数是对arr的引用,因此可以更改数组元素的值。但是,尝试将参数重新分配到不同的内存位置只在方法内部起作用,不会影响原始变量arr。 C


尝试阅读它是了解更多情况的最佳方法。

数组是引用类型

您没有传递数组的副本,而是传递对它的引用

下面是一个较小的程序,演示:

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

public static void Test(int[] arr)
{
    arr[1] = 15;
}
输出:

1
15
3
更详细的描述:当您在C中向方法传递值时,它是默认值,这意味着您传递的是值的副本,而不是实际变量本身

在本例中,您传递的是引用的副本,但引用引用的是数组

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

您的int[]a是一个数组a引用类型,它的地址作为值传递给您的方法summelements,现在方法中的参数a指向内存中的同一对象。因此,一旦您更改了特定索引的值,您就会看到调用者中的更改


您应该看到:

每个引用类型都是通过对数据所在地址的引用来访问的,即使没有标记为引用参数。请参阅下面的列表,了解哪些数据类型是引用类型,哪些是值类型。。这里可以找到非常好的示例和技术细节

值类型 值类型包括以下内容:

All numeric data types
Boolean, Char, and Date
All structures, even if their members are reference types
Enumerations
String
All arrays, even if their elements are value types
Class types, such as Form
Delegates
参考类型 参考类型包括以下内容:

All numeric data types
Boolean, Char, and Date
All structures, even if their members are reference types
Enumerations
String
All arrays, even if their elements are value types
Class types, such as Form
Delegates

在这里,我试图引用你的文章来回答:@tastro:哦,天哪,这些纸片的想法是为了让它更容易。现实世界的类比往往有助于人们——如果这次失败了,我很抱歉:谢谢你提醒我数组和类一样是一种引用类型,我不知何故忘记了我在学校已经学过了此语句表示数组是引用类型。你的答案之所以被我接受。stackoverflow可以添加如下内容。。。用户可以写下为什么选择答案作为他们接受的答案。