今天对 ref 和 out 解析一下
相同:
a、两者都是按地址传递的。
b、使用后都将改变原来参数的数值。
c、若要使用 ref 参数,则方法定义和调用方法都必须显式使用 ref 关键字,若要使用 out 参数,方法定义和调用方法都必须显式使用 out 关键字
不同:
ref 要求变量必须在传递之前进行初始化
eg:
static void Main(string[] args)
{
Program pg = new Program();
string x = "1";
int y = 20;
pg.GetValue(out x, out y);
Console.WriteLine("x={0},y={1}", x, y);
Console.ReadLine();
}
public void GetValue(out string x, out int y)
{
x = "521";
y = 520;
}
static void Main(string[] args)
{
Program pg = new Program();
string x = "1";
int y = 20;
pg.GetValue(ref x, ref y);
Console.WriteLine("x={0},y={1}", x, y);
Console.ReadLine();
}
public void GetValue(ref string x, ref int y)
{
x = "521";
y = 520;
}
以上都输出 x=521,y=520
注:
a、string x = "1"; int y = 20; 使用 out 时 x 和 y 可以不赋初始值;使用 ref 报错 “使用了未赋值的变量”
b、ref 和 out 关键字在运行时的处理方式不同,但在编译时的处理方式相同。因此,如果一个方法采用 ref 参数,
而另一个方法采用 out 参数,则无法重载这两个方法。例如,从编译的角度来看,以下代码中的两个方法是完全相同的,
因此将不会编译以下代码:
class CS0663_Example { // Compiler error CS0663: "Cannot define overloaded // methods that differ only on ref and out". public void SampleMethod(out int i) { } public void SampleMethod(ref int i) { } }
但是,如果一个方法采用 ref 或 out 参数,而另一个方法不采用这两类参数,则可以进行重载,如下所示:
class RefOutOverloadExample
{
public void SampleMethod(int i) { }
public void SampleMethod(out int i) { }
}
注:
out
class Program
{
static void Main(string[] args)
{
string tmp; //先声明,但不初始化
User _user=new User();
_user.Name(out tmp); //调用Name方法
Console.WriteLine("{0}",tmp); //这时tmp的值为“在这里面赋值了”
Console.ReadKey(true);
}
}
class User
{
public void Name(out string tmps)
{
tmps="在这里面赋值了";
}
}
结果:
在这里面赋值了
ref
class Program
{
static void Main(string[] args)
{
string tmp="传值之前"; //声明并初始化 这时如果输出tmp值为"传值之前"
User _user=new User();
_user.Name(ref tmp);
Console.WriteLine("{0}",tmp);
Console.ReadKey(true);
}
}
class User
{
public void Name(ref string tmps)
{
tmps="传值之后";
}
}
结果:
传值之后