最近看到params这个关键字,那就写写ref、out、params吧。
三者都是方法参数的修饰符。使用ref和out时,方法里面对参数的会处理影响到方法外面的值,二者都相当于引用传递。但使用ref和out是有区别的, 用具体的例子解释如下:
控制台输入如下两个函数:
void UseOut(out int n)
{
Console.WriteLine("在UseOut函数内部更改传入的值后的值为:" + n);
}
void UseRef(ref int n)
{
Console.WriteLine("在UseOut函数内部更改传入的值后的值为:" + n);
}
这时会对UseOut函数报两个错误:
从这可以看出来两个结论:out修饰的参数(上例中指的是n)在使用前(方法体内)必须赋值;在方法调用返回之前必须对out修饰的参数赋值。
上面两个结论也正好对应ref,ref修饰的参数不需要这样,这是二者的不同之处。
上面的结论同时也引出来了ref和out得另外一个区别,是什么呢?
就是,out修饰的参数在方法体内使用之前的值与在方法体外对该传递过来的参数赋的值无关,即out修饰的参数在传递之前不需要赋值,但ref修饰的参数传递前一定要赋值。看下面一个例子:
class Program
{
private static void UseOut(out int n)
{
n = 5;//此处不赋值,后面无法使用
Console.WriteLine("在UseOut函数内部初始值值为:" + n);
n = n + 1;
Console.WriteLine("在UseOut函数内部更改后的值为:" + n);
}
private static void UseRef(ref int n)
{
n = n + 1;
Console.WriteLine("在UseOut函数内部更改后的值为:" + n);
}
static void Main(string[] args)
{
int i;//注意此处i没有赋值
UseOut(out i);
Console.WriteLine("调用UseOut函数返回后值为:" + i);
//下面继续使用i的值,调用UseOut函数以后,i已经有值了
UseRef(ref i);
Console.WriteLine("调用UseRef函数返回后值为:" + i);
Thread.Sleep(300000);
}
}
输出结果:
其实上面同时也说明了另外一个问题:ref和out 都可以以引用传递的方式改变函数外部的值,这是二者的共同点。
虽然二者修饰符不一样,运行时的处理方式不同,但是编译时的方式是一样的,所有如果一个方法采用ref参数,另一方方法采用out参数,则无法重载这两个函数。
下面是params:
params 关键字在方法成员的参数列表中使用,为该方法提供了参数个数可变的能力。
例子:
class Program
{
private static void UseParams(params string[] S)
{
string p=String.Empty;
if (S.Length>0)
{
for (int i = 0; i < S.Length; i++)
{
p += S[i] + "----------";
}
Console.WriteLine(p);
}
else
{
Console.WriteLine("NO Params!");
}
}
static void Main(string[] args)
{
Console.WriteLine("First Call:");
UseParams("123", "abc", "000");
Console.WriteLine("Second:");
UseParams();
Thread.Sleep(300000);
}
}
结果: