通过ref与val,变量与数组

时间:2017-03-19 10:35:10

标签: c# arrays pass-by-reference

由val变量:

static void Main(string[] args)
{
    int i = 3;
    method1(i);
    Console.WriteLine(i);
    Console.ReadLine();
}
static void method1(int z)
{
    z *= 2;
}

输出为3,因为method1没有更改Main中的变量。

按参考变量

static void Main(string[] args)
{
    int i = 3;
    method1(ref i);
    Console.WriteLine(i);
    Console.ReadLine();
}
static void method1(ref int z)
{
    z *= 2;
}

输出为6,因为method1更改了Main中的变量。

数组由val:

class Program
{
    static void Main(string[] args)
    {
        int[] i = { 13, 1, 5 };
        method1(i);
        Console.WriteLine(String.Join(",",i));
        Console.ReadLine();
    }
    static void method1(int[] z)
    {
        for(int m=0; m<z.Length;m++)
        {
            z[m] *= 2;
        }
    }
}

输出为26,2,10。

数组来自ref:

class Program
{
    static void Main(string[] args)
    {
        int[] i = { 13, 1, 5 };
        method1(ref i);
        Console.WriteLine(String.Join(",",i));
        Console.ReadLine();
    }
    static void method1(ref int[] z)
    {
        for(int m=0; m<z.Length;m++)
        {
            z[m] *= 2;
        }
    }
}

输出再次为26,2,10。

结论: 变量可以通过值或ref传递, 与只能通过引用传递的数组相反。 这是对的吗? 如果不是 - method1(ref int [] z)和method1(int [] z)之间有什么区别?我们什么时候会得到不同的结果?

1 个答案:

答案 0 :(得分:2)

当引用类型对象按值传递时,对象的引用实际上是按值传递的,因此如果更新对方法实现中新对象的引用,引用将开始指向新的内存地址。

您可以通过稍微修改方法实现来查看结果的差异,以便将即将到来的输入数组初始化为新实例,如:

static void method1(int[] z)
{
   z = new int[3]; // new instance created and z has reference to it
                   // while calling side still refers to old memory location
                   // which is { 13, 1, 5 }
   for(int m=0; m<z.Length;m++)
   {
        z[m] *= 2;
    }
}

现在当你调用pass by value方法时,它将仅在本地为此方法修改z,并且外部数组不会受到影响,而如果通过引用传递它,则两个数组都将受到更改的影响

正在发生的是我们通过创建一个新的数组实例来设置数组z以引用新的内存位置,因此方法中的引用会更新为指向新的内存位置但是调用方引用是仍然指向在调用方法之前实例化的旧数组。

当您通过引用传递时,变量将更新为指向新的内存位置。

static void method1(ref int[] z)
{
   z = new int[3]; // new instance created and z has reference to it
                   // now calling side also refers to new memory location
                   // which is new int[3];
   for(int m=0; m<z.Length;m++)
   {
        z[m] *= 2;
    }
}