(1)传值参数无需额外的修饰符,传址参数需要修饰符ref
传值参数无需额外的修饰符,传址参数需要修饰符ref,输出参数需要修饰符out,数组参数需要修饰符params。传值参数在方法调用过程中如果改变了参数的值,那么传入方法的参数在方法调用完成以后并不因此而改变,而是保留原来传入时的值。传址参数恰恰相反,如果方法调用过程改变了参数的值,那么传入方法的参数在调用完成以后也随之改变。实际上从名称上我们可以清楚地看出两者的含义--传值参数传递的是调用参数的一份拷贝,而传址参数传递的是调用参数的内存地址,该参数在方法内外指向的是同一个存储位置。看下面的例子及其输出:
using System;
class Test
{
static void Swap(ref int x, ref int y)
{
int temp = x;
x = y;
y = temp;
}
static void Swap(int x,int y)
{
int temp = x;
x = y;
y = temp;
}
static void Main()
{
int i = 1, j = 2;
Swap(ref i, ref j);
Console.WriteLine("i = {0}, j = {1}", i, j);
Swap(i,j);
Console.WriteLine("i = {0}, j = {1}", i, j);
}
}
程序经编译后执行输出:
i = 2, j = 1
i = 2, j = 1
我们可以清楚地看到两个交换函数Swap()由于参数的差别--传值与传址,而得到不同的调用结果。注意传址参数的方法调用无论在声明时还是调用时都要加上ref修饰符。
(2)从一个比较引出ref
ref变量在调用函数前需初始化.
out变量不一定要在调用函数前初始化.
如:
string s;
func1(ref s);//出错
func2(out s); //正确
又如:string s="";
func1(ref s);//正确
func2(out s); //正确
(3)文档参考:
C# 关键词 | 方法参数
方法参数中的 ref 方法参数关键词可使方法参考到传递至该方法的相同变量。此参数在方法中造成的任何变更将会在控制权传递回呼叫方法时反映至该变量。
若要使用 ref 参数,此自变量必须明确地以 ref 自变量形式传递到方法中。ref 自变量值将会传递给 ref 参数。
传递给 ref 参数的自变量必须先被初始化。将此点与 out 参数进行比较,可知其自变量在传递至 out 参数之前并不一定要先明确地初始化。
属性并不是变量因此无法以 ref 参数传递。
如果两个方法的宣告仅在 ref 的使用方法不同时,就会产生多载。但是却无法定义仅在 ref 和 out 有所不同的多载。举例来说,下列多载宣告是有效的:
class MyClass
{
public void MyMethod(int i) {i = 10;}
public void MyMethod(ref int i) {i = 10;}
}
但下列多载宣告是无效的:
class MyClass
{
public void MyMethod(out int i) {i = 10;}
public void MyMethod(ref int i) {i = 10;}
}
如需传递数组的详细信息,请参阅使用 ref 和 out 传递数组。
范例
// cs_ref.cs
using System;
public class MyClass
{
public static void TestRef(ref char i)
{
i = 'b';
}
public static void TestNoRef(char i)
{
i = 'c';
}
public static void Main()
{
char i = 'a';
TestRef(ref i);
Console.WriteLine(i);
TestNoRef(i);
Console.WriteLine(i);
}
}
输出
b
b