通常,向方法传递一个实参时,对应的参数(形参)会用实参的一个副本来初始化。不管形参是值类型(如int),可空类型(如int?),还是引用类型(如string),这一点都是成立的。换言之,谁边在方法内部进行什么修改,都不会影响作为参数来传递的一个变量的原始值。如
public static void DoIncrement(int element)
{
element++;
Console.WriteLine("element={0}",element);
}
static void Main(string[] args)
{
int number = 2;
DoIncrement(number);//element输出3
Console.WriteLine("number={0}",number);//number输出2
}
在少数情况下,我们希望一个方法能实际的修改一个实参,为此,C#就提供了ref和out。
1、ref
如果为一个参数(形参)附加了一个ref关键字作为前缀,该参数就会成为实参的一个别名(或者对实参的一个引用),而不在是实参的一个副本。使用ref时,像参数应用的任何操作都会同样应用于实参 ,因为参数(形参)和实参引用的是同一个对象。实参也必须附加ref关键字作为前缀,明确说明实参将会改变:
如:
public static void DoIncrement(ref int element)
{
element++;
Console.WriteLine("element={0}",element);
}
static void Main(string[] args)
{
int number = 2;
DoIncrement(ref number);//element输出3
Console.WriteLine("number={0}",number);//number输出3
}
“变量是用前必须赋值”这个规则同样适用于ref实参,如
static void Main(string[] args)
{
int number ;//未初始化,编译会出错
DoIncrement(ref number);//element输出3
Console.WriteLine("number={0}",number);//number输出3
}
2.out
编译器会在调用方法前,验证他的ref参数是否已被赋值,然而某些时候,我们可能希望由方法本身来初始化参数,所以希望向其传递一个未初始化的实参,于是就有了out关键字。
out和ref用法和作用非常类似,差别在于,在向方法传递一个out参数之后,必须在方法内部对其进行赋值。如:
public static void DoIncrement(out int element)
{
element = 2;//初始化
element++;
Console.WriteLine("element={0}",element);
}
static void Main(string[] args)
{
int number ;
DoIncrement(out number);//element输出3
Console.WriteLine("number={0}",number);//number输出3
}