C# ref深入理解
做.NET开发的人,肯定对ref和out关键字非常了解:
ref功能:
ref 关键字使参数按引用传递。其效果是,当控制权传递回调用方法时,在方法中对参数所做的任何更改都将反映在该变量中。简单点说就是,使用了ref和out的效果就几乎和C中使用了指针变量一样。它能够让你直接对原数进行操作,而不是对那个原数的Copy进行操作。
{
static void Main(string[] args)
{
int[] arr = {100,200,300};
Console.WriteLine("调有方法前:");
foreach (int item in arr)
{
Console.Write(item+"\t");
}
Console.WriteLine("\n------------------------------------");
//调用方法
RefDemo1(arr);
Console.WriteLine("调有方法后:");
foreach (int item in arr)
{
Console.Write(item+"\t");
}
Console.WriteLine();
}
static void RefDemo1(int[] parr)
{
parr = new int[5] { 1, 2, 3, 4, 5 };
}
{
static void Main(string[] args)
{
int[] arr =
Console.WriteLine("调有方法前:");
foreach (int item in arr)
{
Console.Write(item+"\t");
}
Console.WriteLine("\n------------------------------------");
//调用方法
RefDemo2(ref arr);
Console.WriteLine("调有方法后:");
foreach (int item in arr)
{
Console.Write(item+"\t");
}
Console.WriteLine();
}
static void RefDemo2(ref int[] parr)
{
parr = new int[5] { 1, 2, 3, 4, 5 };
}
调有方法前:
100 200 300
------------------------------------
调有方法后:
100 200 300
请按任意键继续. . .
分析结果:对于案例1,首先 {100,200,300};在堆中划分内存空间,假设开辟的内存空间地址为0X7799,则栈中的arr中存放0X7799,即,arr指向堆中开辟的内存空间,调用 RefDemo1方法时,给形参在栈中开辟内存空间,并传arr的内容到parr中,这样arr和parr中的内容都是0X7799,即都指向堆中的同一空间,后面执行parr = new int[5] { 1, 2, 3, 4, 5 };时,因为new会重新开辟新的内存空间,这样导致parr重新赋了新的地址,这样parr中的内容与arr中的内容已经不是同一个地址,但是arr中的内容并没有发生变化,还指向最初在堆中开辟的空间,所以打印前后结果是一样的,如上面结果所示。
案例2答案:
调有方法前:
100 200 300
------------------------------------
调有方法后:
1 2 3 4 5
请按任意键继续. . .
分析结果:对于案例2,首先 {100,200,300};在堆中划分内存空间,假设开辟的内存空间地址为0X7799,则栈中的arr中存放0X7799,即,arr指向堆中开辟的内存空间,调用 RefDemo1方法时,因为是ref传参,这样arr就有了一个别名叫parr(即在栈中不再开辟新的空间给parr,也就是arr和parr的地址是一样的,内容也是一样的,且都指向刚开辟的堆中的空间),后面执行parr = new int[5] { 1, 2, 3, 4, 5 };时,因为new会重新开辟新的内存空间,这样导致parrt和arr重新赋了新的地址,这样parr中的内容与arr中的内容也是同一个地址,它们一起指向新开辟的堆中的空间,所以打印前后结果是一不样的,如上面结果所示。
总结:ref的参数传递,形参的改变一定会影响到实参。
浙公网安备 33010602011771号