ref
通常我们向方法中传递的是值方法获得的是这些值的一个拷贝然后使用这些拷贝当方法运行完毕后这些拷贝将被丢弃而原来的值不将受到影响此外我们还有其他向方法传递参数的形式引用(ref)和输出(out)
有时我们需要改变原来变量中的值这时我们可以向方法传递变量的引用而不是变量的值引用是一个变量他可以访问原来变量的值修改引用将修改原来变量的值变量的值存储在内存中可以创建一个引用他指向变量在内存中的位置当引用被修改时修改的是内存中的值因此变量的值可以将被修改当我们调用一个含有引用参数的方法时方法中的参数将指向被传递给方法的相应变量因此我们会明白为什么当修改参数变量的修改也将导致原来变量的值
创建参数按引用传递的方法需使用关键字ref例;
using System;
class gump
{
public double square(ref double x)
{
x=x*x;
return x;
}
}
class TestApp
{
public static void Main()
{
gump doit=new gump();
double a=;
double b=;
ConsoleWriteLine(\Before square>a={}b={}\ab);
b=doitsquare(ref a);
ConsoleWriteLine(\After square>a={}b={}\ab);
}
}
通过测试我们发现a的值已经被修改为了
out
通过指定返回类型可以从方法返回一个值有时候(也许还没遇到但是我们应该有这么个方法)需要返回多个值虽然我们可以使用ref来完成但是C#专门提供了一个属性类型关键字为out介绍完后我们将说明ref和out的区别
通过使用out关键字我们改变了三个变量的值也就是说out是从方法中传出值
using System;
class gump
{
public void math_routines(double xout double halfout double squaredout double cubed)
//可以是:public void math_routines(//ref double xout double halfout double squaredout double cubed)
//但是不可以这样:public void math_routines(out double xout double halfout double squaredout double cubed)对本例来说因为输出的值要靠x赋值所以x不能再为输出值
{
half=x/;
squared=x*x;
cubed=x*x*x;
}
}
class TestApp
{
public static void Main()
{
gump doit=new gump();
double x=;
double half=;
double squared=;
double cubed=;
[Page]
/*
double x=;
double half;
double squared;
double cubed;
*/
ConsoleWriteLine(\Before method>x={}\x);
ConsoleWriteLine(\half={}\half); ConsoleWriteLine(\squared={}\squared);
ConsoleWriteLine(\cubed={}\cubed);
doitmath_rountines(xout halfout squaredout cubed);
ConsoleWriteLine(\After method>x={}\x);
ConsoleWriteLine(\half={}\half);
ConsoleWriteLine(\squared={}\squared);
ConsoleWriteLine(\cubed={}\cubed);
}
}
我们发现ref和out似乎可以实现相同的功能因为都可以改变传递到方法中的变量的值但是二者本质本质的区别就是ref是传入值out是传出值在含有out关键字的方法中变量必须由方法参数中不含out(可以是ref)的变量赋值或者由全局(即方法可以使用的该方法外部变量)变量赋值out的宗旨是保证每一个传出变量都必须被赋值
上面代码中被/**/注释掉的部分可以直接使用也就是说在调用方法前可以不初始化变量但是\x\是要赋值的否则要报错而ref参数在传递给方法时就已经是还有值的了所以ref侧重修改out侧重输出