在进行函数的参数调用时,分为下面三种情况:
1、如果传递的参数是基元类型(int、float、string等)或结构体(struct),那么就是传值调用。
2、如果传递的参数前面有ref或者out关键字,那么就是传引用调用。
3、一般如果传递是类(Class)那么就是传引用调用。
请注意第三种种情况,我用的词语是“一般”。具体如何调用下面我会详细讲解。
第一种情况大家应该没有什么异议。传递这些基元类型并不会改变这些参数在本函数体内的值。譬如下面的例子:
例1:
void TestRefAndOut()
{
string s1 = "Hello World!";
Test(s1);
Console.WriteLine(s1); //output: Hello World!
Console.ReadKey();
}
void Test(string str)
{
str = "Hi, I have changed!";
}
第二种情况是使用关键字Ref和Out关键字,这两个关键字使参数按引用方式传递。即当控制传递回调用方法时,在被调用的方法中对参数所做的任何改变都将反应在该变量中。譬如下面的两个例子:
例2:
void TestRefAndOut()
{
string s1 = "Hello World!"; //必须初始化,否则会报错误:使用了未赋值的局部变量"s1"。
TestRef(ref s1);
Console.WriteLine(s1); // output : Hi, I have changed!
Console.ReadKey();
}
void TestRef(ref string str)
{
str = "Hi, I have changed!";
}
例3:
void TestRefAndOut()
{
string s1; //不必初始化,因为out参数在进入被调用的方法时会清空它的一切引用,即成为一个空引用。
TestOut(out s1);
Console.WriteLine(s1); // output : Hi, I have changed!
Console.ReadKey();
}
void TestOut(out string str)
{
str = "Hi, I have changed!"; //必须进行赋值,因为此时的"str"是一个空引用,在调用函数体的输出过程中会报错误:使用了未赋值的局部变量"s1".
}
通过上面的两个例子我们可以总结出这两个关键字的区别:Ref关键字在使用时必须初始化参数,而Out关键字在使用时则不必初始化参数,但是必须在被调用方法内部对其进行赋值,因为它已经是个空引用了,必须赋值,才能继续使用。
在用法上概括下就是:out适合在需要return多个返回值的地方。而ref则用在需要被调用的方法修改调用者的引用的时候。