[C#基础知识]Ref 关键字在修饰在引用类型时的行为

这是个老话题了,不过还是有一些初学者不是太明白,这个也是在面试时容易问的问题。

 

试验1:Ref对于改变引用对象的属性时的影响

using System;

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对于在方法内部改变其指向对象时影响

 

using System;

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修饰的引用参数才能使再分配操作应用于外部。

 

小结:

  1. 当没有Ref修饰引用类型的参数时,在方法中只能改变此引用参数的属性内容,而不能改变整个引用参数对象本身。
  2. 当有Ref修饰引用类型的参数时,则可以在方法中改变此引用参数的指向位置,而不仅是其属性内容。
  3. 当一个引用类型传给一个方法时,是传递了这个引用类型对象的引用的副本(不是对象本身),所以对于在调用方法外部的引用和方法中的引用来说,这两个引用都指向堆上的同一个对象。所以在修改此对象的属性值时,修改同时会应用于内部和外部的两个引用上。但重新分配其引用位置时,则只是修改副本引用的引用位置,原引用(方法外部)的位置不变,原引用还是指向原来的对象。
  4. 而如果加上Ref关键字,这时传入的参数则为些引用对象的原始引用,而不是引用的副本,这样的话,你就不但可以修改原始引用对象的内容,还可以再分配此引用的引用位置(用New 来重新初始化)。
  5. 如果你只想在方法中改变引用参数的内容,没有必要使用Ref来修饰引用参数。
  6. 如果你希望在方法中改变引用对象参数的引用(调用方法外的),如重新初始化对象,则需要使用Ref关键字来修饰参数。
 
posted @ 2011-12-16 09:13  sujiantao  阅读(2848)  评论(3编辑  收藏  举报