C#中引用类型的变量做为参数在方法调用时加不加 ref 关键字的不同之处
程序员文章站
2022-06-19 14:45:34
一直以为对于引用类型做为参数在方法调用时加不加 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
*/
}
}
}
一些说明:
- 以上代码中的注释可纵向分隔为两部分来看,左边部分是不加ref关键字调试时查看的内存情况,右边则是加上ref关键字后的情况。
- 每个/* */中注释都是代码执行完注释所在位置的上一语句后的内存情况。
- &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