欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C#中引用类型的变量做为参数在方法调用时加不加 ref 关键字的不同之处

程序员文章站 2022-03-10 17:33:55
一直以为对于引用类型做为参数在方法调用时加不加 ref 关键字是没有区别的。但是今天一调试踪了一下变量内存情况才发现大有不同。直接上代码,以下代码是使用了ref 关键字的版本。它输出10。如果不使用ref 关键字则输出 1,2,3 class Program { static void Main(string[] args) { int[] myArray = new int[] { 1, 2, 3 }; .....

一直以为对于引用类型做为参数在方法调用时加不加 ref 关键字是没有区别的。但是今天一调试踪了一下变量内存情况才发现大有不同。

直接上代码,以下代码是使用了 ref 关键字的版本。它输出10。如果不使用ref 关键字则输出 1,2,3 

    class Program
    {
        static void Main(string[] args)
        {
            int[] myArray = new int[] { 1, 2, 3 };
            new SetClass().SetArray(ref myArray);
            /*
             不加ref关键字的引用类型传参情况                                    加上ref关键字后的引用类型传参情况
             &myArray                                                           &myArray
                0x000000c088d7e3d0                                                  0x0000008151b7e6b0
                *&myArray: 0x0000029b3f84ae00                                       *&myArray: 0x000001c5e5a7ae00
            */

            foreach (int i in myArray)
                Console.WriteLine(i);
            /*
             &myArray                                                           &myArray
                0x000000c088d7e3d0                                                  0x0000008151b7e6b0
                *&myArray: 0x0000029b3f84ae00                                       *&myArray: 0x000001c5e5a7ae00
            */
        }

    }

    class SetClass
    {
        //如果形参 array 是引用类型时(不论加不加 ref 关键字),则在方法执行时方法体内的局部变量 array 指向外部传进来的实参所指向的内存空间。
        //但是加上 ref 关键后在方法执行时方法体内接收传进来的实参时,并不会给 array 变量分配内存空间,即 变量array就是变量myArray。 
        internal void SetArray(ref int[] array)
        {
            /*
             &array                                                           &myArray
                0x000000c088d7e388                                                0x0000008151b7e6b0
                *&array: 0x0000029b3f84ae00                                       *&myArray: 0x000001c5e5a7ae00
            */
            array = new int[] { 10 };
            /*
             &array                                                            &myArray
                0x000000c088d7e388                                                 0x0000008151b7e6b0
                *&array: 0x0000029b3f84bbf0                                        *&myArray: 0x000001c5e5a7ae00
             */
        }
    }
}

一些说明:

  1. 以上代码中的注释可纵向分隔为两部分来看,左边部分是不加ref关键字调试时查看的内存情况,右边则是加上ref关键字后的情况。
  2. 每个/* */中注释都是代码执行完注释所在位置的上一语句后的内存情况。
  •              &myArray                         //表示获取这个变量内存的指令

                0x000000c088d7e3d0            //表示这个变量在内存中的地址
                *&myArray: 0x0000029b3f84ae00  //表示这个变量指向的内存空间的对象的地址

  •         在visual studio 2019 中查看变量内存地址的方法:

        方法一:
        在即时窗口输入取地址符+变量名如 &a 这是会输出如下 两行:
        0x000000325637e570
        *&a: 0x00000209ba0dad58
        第一行 0x000000325637e570 代表变量本身的内存地址,第二行 *&a: 0x00000209ba0dad58 表示变量指向的对象的内存地址

        方法二:
        【调试】-【窗口】-【内存】-从列出来的4个中选一个,然后会调出内存查看窗口。在内存查看地窗口中的【地址】里输入[取地址符]+[变量名]如 &a ,这时地址中的&a会变成变量的十进制表示的内存地址,如:0x000000325637E570

 

补充几张调试中断在不同语句时的一些内存情况截图:(加上ref关键字后的引用类型传参情况图)

1.

C#中引用类型的变量做为参数在方法调用时加不加 ref 关键字的不同之处

2.

C#中引用类型的变量做为参数在方法调用时加不加 ref 关键字的不同之处

3.

C#中引用类型的变量做为参数在方法调用时加不加 ref 关键字的不同之处

4.

C#中引用类型的变量做为参数在方法调用时加不加 ref 关键字的不同之处
 

本文地址:https://blog.csdn.net/hrx521/article/details/112250508