原文:C#关于ref与out的总结
首先大概说下函数调用的过程,首先为被调用函数分配存储空间(分为代码区和变量区)之后将调用函数传递过来的变量压栈,然后逐一弹栈进行处理,之后进行运算,将需要返回的变量压栈,然后释放存储空间,返回调用函数,继续执行下面的代码。
所以在这里就有一个问题,如果我们想要把在被函数中对参数值的修改传回给调用函数怎么办(除了我们可以用return返回一个执行结果)。
在c语言中提供了指针变量,我们可以灵活的运用指针型变量进行参数地址的互相传递,并实现了对同一存储空间的变量的操作。这样当调用函数的时候,在被调用函数中对参数的修改就会直接操作调用函数变量的存储空间,这样就得到了保存。
在c++中取缔了指针变量,因为它是类型不安全的,容易引起系统的崩溃。取而代之的是引用,所谓引用就是当我们调用函数的时候,编译器会将调用函数的变量名重命名为调用函数的变量名,这样我们在被调用函数中对变量的操作,就是直接对调用函数的变量操作,这样就得到了保存。
在C#中同样使用了引用。今天特别记录下C#中提供了两个,一个是ref,还有一个是out。这两个引用是有区别的,按照C#中的说法:ref叫做引用参数,要传递值并原地修改它(也就是在相同的内存位置),用引用参数就很方便。因为传递了一个变量给该方法(不仅仅是它的值),这里调用被调用函数的时候变量必须被初始化。
out叫做输出参数,传递参数可以把它设作一个输出参数。一个输出参数仅用于从方法传递回一个结果。它和引用参数的另一个区别在于:调用者不必先初始化变量才调用方法。(我的理解这里其实就是实现多个return,返回多个运行结果)
e.g:
1> 在此例中,在调用方(Main 方法)中声明数组 theArray,并在
FillArray
方法中初始化此数组。然后将数组元素返回调用方并显示。
class TestOut
{
static void
FillArray(out int[] arr)
{
// Initialize the array:
arr = new int[5] { 1, 2, 3, 4, 5 };
}
static void
Main()
{
int[] theArray; // Initialization is not required
// Pass the array to the callee using
out:
FillArray(out theArray);
// Display the array
elements:
System.Console.WriteLine("Array
elements are:");
for (int i = 0; i < theArray.Length;
i++)
{
System.Console.Write(theArray[i] + " ");
}
// Keep the console window open in debug
mode.
System.Console.WriteLine("Press
any key to exit.");
System.Console.ReadKey();
}
}
2> 在此例中,在调用方(Main 方法)中初始化数组 theArray,并通过使用
ref 参数将其传递给 FillArray 方法。在
FillArray
方法中更新某些数组元素。然后将数组元素返回调用方并显示。
class TestRef
{
static void
FillArray(ref int[] arr)
{
// Create the array on
demand:
if (arr == null)
{
arr = new int[10];
}
// Fill the array:
arr[0] = 1111;
arr[4] = 5555;
}
static void
Main()
{
// Initialize the array:
int[] theArray = { 1, 2, 3, 4, 5
};
// Pass the array using
ref:
FillArray(ref theArray);
// Display the updated
array:
System.Console.WriteLine("Array
elements are:");
for (int i = 0; i < theArray.Length;
i++)
{
System.Console.Write(theArray[i] + " ");
}
// Keep the console window open in debug
mode.
System.Console.WriteLine("Press
any key to exit.");
System.Console.ReadKey();
}
}
特此记录,感谢论坛上的帖子及相关文章。