默认情况下,CLR假定所有方法参数都是传值的。
  对于引用类型,对一个对象的引用(指向对象的一个指针)会传给方法,但是这个引用本身是以传值的方式传给方法的。方法能修改对象,调用者能看到这些修改。
  对于值类型,传给方法的是实例的一个副本。方法获得的是一个值类型实例副本,所以调用者中的实例不受影响
  代码如下:

namespace refDemo2
{
    class Program
    {
        static void Main(string[] args)
        {
            int i = 5;
            AddI(i);
            Console.WriteLine(i);//显示"5",i的值并没有改变
            Console.ReadKey();
        }

        private static void AddI(int v)//v获得的是i的一个副本,调用者中的实例不受影响
        {
            v+= 10;
        }
    }
}

 

一,为值类型使用ref和out

namespace refDemo2
{
    class Program
    {
        static void Main(string[] args)
        {
            int i = 5;
            AddI(ref i);
            Console.WriteLine(i);//显示"15",i的值被改变了
        Console.ReadKey();
        }

        private static void AddI(ref int v)//v获得的是一个指向实例对象(值5)的指针
        {
            v+= 10;
        }
    }
}

 

二,为引用类型使用ref和out

 

namespace refDemo3
{
    class Program
    {
        static void Main(string[] args)
        {
            string s1 = "Tmac";
            string s2 = "Mcgrady";

            Swap(s1,s2);//没有使用ref
            Console.WriteLine(s1);//显示"Tmac"
            Console.WriteLine(s2);//显示"Mcgrady",为什么值没有交换呢???
        }

        private static void Swap(string a, string b)//a和b获取的是一个分别指向对象s1和s2的指针
        {
            string t = b;
            b = a;
            a = t;
        }
    }
}

 

  容易困惑的地方:s1,s2是引用类型,传给方法Swap的肯定也是指向实例的一个指针,那理论上来讲调用了Swap方法之后s1和s2的值要交换呀,可是实际结果并不如我们所愿,这是为什么呢?
  答:就如文章一开头讲的,默认情况下,CLR假定所有方法参数都是传值的,虽然s1和s2是引用类型,调用方法时传递的也是指向实例的指针,但是,指针本身还是以传值方式传给方法的。所以调用者中实例的值并没有得到改变。

  要达到我们想要的效果,所以还是必须得使用ref,代码如下:

namespace refDemo3
{
    class Program
    {
        static void Main(string[] args)
        {
            string s1 = "Tmac";
            string s2 = "Mcgrady";

            Swap(ref s1,ref s2);
            Console.WriteLine(s1);//显示"Mcgrady"
            Console.WriteLine(s2);//显示"Tmac"
        }

        private static void Swap(ref string a,ref string b)//a和b获取的是一个分别指向对象s1和s2的指针
        {
            string t = b;
            b = a;
            a = t;
        }
    }
}

 总结:1,从IL和CLR的角度看,ref和out是一样的,它们都会生成相同的IL代码,都导致传递指向实例的一个指针。

   2,ref一般用在方法内部对外部的值进行改变的时候。而out一般用在方法有多个返回值的时候。

posted on 2012-06-09 10:24  永远的麦子  阅读(675)  评论(0编辑  收藏  举报