[转载][C#基础知识]Ref 关键字在修饰在引用类型时的行为 – sujiantao – 博客园.
这是个老话题了,不过还是有一些初学者不是太明白,这个也是在面试时容易问的问题。
试验1:Ref对于改变引用对象的属性时的影响
namespace SOVT
{
class Program
{
static void Main()
{
MyClass myClass=new MyClass();
Console.WriteLine(myClass.Field);
ChangeMyClass(myClass);
Console.WriteLine(myClass.Field);
ChangeMyClass(ref myClass);
Console.WriteLine(myClass.Field);
Console.ReadKey();
}
public class MyClass
{
public int Field;
}
public static void ChangeMyClass(MyClass myClass)
{
myClass.Field = 1;
}
public static void ChangeMyClass(ref MyClass myClass)
{
myClass.Field = 2;
}
}
}
其运行结果为:
结论:对于引用对象,无论是否有Ref关键字修饰,都能改变其调用方法外部的引用的对象的字段值,用不用Ref无影响。
试验2:Ref对于在方法内部改变其指向对象时影响
namespace SOVT
{
class Program
{
static void Main()
{
MyClass myClass=new MyClass();
Console.WriteLine(myClass.Field);
ChangeMyClass(myClass);
Console.WriteLine(myClass.Field);
ChangeMyClass(ref myClass);
Console.WriteLine(myClass.Field);
Console.ReadKey();
}
public class MyClass
{
public int Field;
}
public static void ChangeMyClass(MyClass myClass)
{
myClass = new MyClass {Field = 1};
}
public static void ChangeMyClass(ref MyClass myClass)
{
myClass = new MyClass { Field = 2 };
}
}
}
运行结果:
结论:对于再分配引用对象的引用的操作,没有Ref修饰时是不能在外部生效的,只有有Ref修饰的引用参数才能使再分配操作应用于外部。
小结:
- 当没有Ref修饰引用类型的参数时,在方法中只能改变此引用参数的属性内容,而不能改变整个引用参数对象本身。
- 当有Ref修饰引用类型的参数时,则可以在方法中改变此引用参数的指向位置,而不仅是其属性内容。
- 当 一个引用类型传给一个方法时,是传递了这个引用类型对象的引用的副本(不是对象本身),所以对于在调用方法外部的引用和方法中的引用来说,这两个引用都指 向堆上的同一个对象。所以在修改此对象的属性值时,修改同时会应用于内部和外部的两个引用上。但重新分配其引用位置时,则只是修改副本引用的引用位置,原 引用(方法外部)的位置不变,原引用还是指向原来的对象。
- 而如果加上Ref关键字,这时传入的参数则为些引用对象的原始引用,而不是引用的副本,这样的话,你就不但可以修改原始引用对象的内容,还可以再分配此引用的引用位置(用New 来重新初始化)。
- 如果你只想在方法中改变引用参数的内容,没有必要使用Ref来修饰引用参数。
- 如果你希望在方法中改变引用对象参数的引用(调用方法外的),如重新初始化对象,则需要使用Ref关键字来修饰参数。