在C#的函数中,存在这样两种情况,当我们将一个值类型变量作为参数传入函数中时,当我们在函数内部修改了这一变量,再次进行输出打印时,会发现在函数外部,变量的值并没有被修改;同样的,当我们将一个引用类型的变量作为参数传入函数中时,如果我们在函数内部重新声明了这一变量,再次进行输出时,会发现它在外部仍然没有被修改。用代码来表示的话,就是

using System;
namespace experiment{
    class program{
        static void ChangeValues(int values)
        {
            values = 3;
        }
        static void ChangeArrayValues(int[] arr)
        {
            arr = new int[] {100,200,300};
        }

        static void Main(string[] args)
        {
            int a = 1;
            int[] arr2 = {1,2,3};
            ChangeValues(a);
            ChangeArrayValues(arr2);
            Console.WriteLine(a);
            Console.WriteLine(arr2[0]);    
        }
}

对于前一种情况,我们可以这样解释,当a作为一个参数传入时,函数实际上执行了一个values = a的赋值操作,对于值类型的变量,这样的赋值操作相当于在栈内新开辟空间并进行内容的拷贝复制,那么改变函数内改变values的值,和a是没有任何关系的;同理,对于arr2,当传入函数中时同样进行了arr = arr2的赋值操作,此时,两个数组指向堆内的同一片空间,但此时,函数内部有将arr重新声明,相当于在堆内又开辟了一片空间,并使arr指向新的那片堆空间,那么此时,对arr的任何赋值操作,也就和传入而当arr2没有任何关系了。

那么,如果我们希望改变这两种情况,即对于传入函数中的值类型的变量,在内部重新赋值后,使的外部的值也跟着改变,或者对于传入函数中的引用类型的变量,在内部重新声明后,外部的值同样改变,此时就要用到ref和out关键字了,其语法是这样的:

using System;
namespace experiment{
    class program{
        static void ChangeValuesRef( ref int values)
        {
            values = 3;
        }
        static void ChangeArrayValuesRef(ref int[] arr)
        {
            arr = new int[] {100,200,300};
        }
        static void ChangeValuesOut(out int values)
        {
            values = 10;
        }
        static void ChangeArrayValuesOut(out int[] arr)
        {
            arr = new int[] {1000,2000,3000};
        }

        static void Main(string[] args)
        {
            int a = 1;
            int[] arr2 = {1,2,3};
            ChangeValuesRef(ref a);
            ChangeArrayValuesRef(ref arr2);
            Console.WriteLine(a);
            Console.WriteLine(arr2[0]);
            ChangeValuesOut(out a);
            ChangeArrayValuesOut(out arr2);    
        }
}

即将传入的参数前加上ref或out关键字即可,均可以实现内变外也变的效果。

而ref与out之间的区别就在于,使用ref关键字传入的变量必须在外部提前初始化,可以内部不进行修改,而使用out关键字传入必须在内部进行赋值,而可以在外部不预先初始化

通过以上关键字,我们就可以实现在函数内部修改从外部传入的参数值的功能。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐