一、关键字ref的使用:
- 参数为简单类型的例子
static void Main(string[] args)
{
string temp = "a";
Change(temp);
Console.WriteLine(temp);
ChangeByRef(ref temp);
Console.WriteLine(temp);
Console.ReadKey();
}
private static void Change(string temp)
{
temp = temp + "--changed";
}
private static void ChangeByRef(ref string temp)
{
temp = temp + "--refchanged";
}
输出结果:
a
a--refchanged
● 在Change()方法中,虽然改变了temp的值,但方法没有返回值,输出temp依然是初始值a;
● 在ChnageByRef()方法中,由于加上了关键字,虽然也没有返回值,当改变temp的值后,temp的引用地址发生了改变,再次输出, temp的值为新的引用地址对应的值。
- 参数是类类型的例子
class Program
{
static void Main(string[] args)
{
Pet p = new Pet(){Age = 5};
Console.WriteLine("初始年龄是:{0}", p.Age);
ChangeAge(p);
Console.WriteLine("改变pet的属性值后,年龄是:{0}", p.Age);
ChangeAgeByRef(ref p);
Console.WriteLine("改变pet引用地址后,年龄是:{0}", p.Age);
Console.ReadKey();
}
private static void ChangeAge(Pet p)
{
p.Age = 10;
}
private static void ChangeAgeByRef(ref Pet p)
{
p = new Pet(){Age = 20};
}
}
public class Pet
{
public int Age { get; set; }
}
输出结果:
初始年龄是:5
改变pet的属性值后,年龄是:10
改变pet引用地址后,年龄是:20
● 在ChangeAge()方法中,改变的是Pet实例的属性值。
● 在ChangeAgeByRef()方法中,改变的Pet实例的引用地址。
总结:方法参数无论是简单类型,还是类类型,当在其前加上ref关键字后,对参数的赋值,实际上是改变的是方
法参数变量的引用地址。使用ref注意点:● 使用带ref的方法之前,需要给方法参变量赋上初始值
● 无论是定义方法还是使用方法,都要带上关键字ref
二、关键字ref与out的区别
1.两者都是按地址传递的,使用后都将改变原来参数的数值。ref是传递参数的地址,out是返回值。2.使用ref前必须对变量赋值,out不用;进入out的函数时会清空变量,即使变量已经赋值也不行,退出函数时所有out引用的变量都要赋值,ref引用的可以修改,也可以不修改。
例子
using System;
class TestApp
{
static void outTest(out int x, out int y)
{//离开这个函数前,必须对x和y赋值,否则会报错。
//y = x;
//上面这行会报错,因为使用了out后,x和y都清空了,需要重新赋值,即使调用函数前赋过值也不行
x = 1;
y = 2;
}
static void refTest(ref int x, ref int y)
{
x = 1;
y = x;
}
public static void Main()
{
//out test
int a,b;
//out使用前,变量可以不赋值
outTest(out a, out b);
Console.WriteLine("a={0};b={1}",a,b);
int c=11,d=22;
outTest(out c, out d);
Console.WriteLine("c={0};d={1}",c,d);
//ref test
int m,n;
//refTest(ref m, ref n);
//上面这行会出错,ref使用前,变量必须赋值
int o=11,p=22;
refTest(ref o, ref p);
Console.WriteLine("o={0};p={1}",o,p);
}
}
输出结果:
a=1;b=2
c=1;d=2
o=1;p=1
总结:ref和out的区别在C# 中,既可以通过值也可以通过引用传递参数。通过引用传递参数允许函数成员更改参数的值,并保持该更改。若要通过引用传递参数,可使用ref或out关键字。ref和out这两个关键字都能够提供相似的功效,其作用也很像C中的指针变量。它们的区别是:
1、使用ref型参数时,传入的参数必须先被初始化。对out而言,必须在方法中对其完成初始化, 必须方法返回之前为 out 参数赋值。
2、使用ref和out时,在方法的参数和执行方法时,都要加Ref或Out关键字。以满足匹配。
3、out适合用在需要retrun多个返回值的地方,而ref则用在需要被调用的方法修改调用者的引用的时候。
注: 在C#中,方法的参数传递有四种类型:传值(by value),传址(by reference),输出参数(by output),数组参数(by array)。传值参数无需额外的修饰符,传址参数需要修饰符ref,输出参数需要修饰符out,数组参数需要修饰符params。传值参数在方法调用过程中如果改变了参数的值,那么传入方法的参数在方法调用完成以后并不因此而改变,而是保留原来传入时的值。传址参数恰恰相反,如果方法调用过程改变了参数的值,那么传入方法的参数在调用完成以后也随之改变。实际上从名称上我们可以清楚地看出两者的含义--传值参数传递的是调用参数的一份拷贝,而传址参数传递的是调用参数的内存地址,该参数在方法内外指向的是同一个存储位置。