一直以为对于引用类型做为参数在方法调用时加不加 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.

2.

3.

4.

 

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