C#中ref out

 因为C#中参数默认是引用的,所以一直没注意ref及out参数修饰符的作用。一般的参考资料也没说清楚这二者的作用。

  其实可以这样理解:ref及out就相当于C/C++中的对参数取指针,使用时就相当于把该参数的实际地址传到函数中,可以在函数中对其进行赋值。而指针与引用的差别在这里也是可以体现出来的:

 class TestApp

    {

 

        public static  void foo1(StringBuilder s)

        {

            s.Append(" World");

            s = new StringBuilder("foo1");

        }

 

        public static  void foo2(ref StringBuilder s)

        {

            s.Append(" World");

            s = new StringBuilder("foo2");

        }

 

        public static void Main()

        {

            StringBuilder s = new StringBuilder("Hello");

           

            foo1(s);

           Console.WriteLine(s.ToString());

            foo2(ref s);

            Console.WriteLine(s.ToString());

 

            Console.ReadLine();

        }

 

    }   

}

  这里的两次输出将分别是“Hello World”和“foo2”。通过这个例子应该可以较明显地区分加和不加ref的区别了。

  而ref与out的区别就在于out类型的参数可以不必初始化,就是说可以未初始化的变量到函数体内,而必须在函数体内对该参数变量赋值。使用了ref或out后,在调用函数时参数必须显式地写明ref或out,且必须是lvalue。 
两个区别是:第一个函数的new出来的是在一个新地址上。。原先stringbuilder的改变只是加个"Hello,World"..
第二个保证了地址不变的地方new。因此替换了原先位置的值为foo2 


---------------------------------------------------------------------------------------------------------

  ref是传递参数的地址,out是返回值,两者有一定的相同之处,但是也有不同点。

  使用ref前必须对变量赋值,out不用。

  out的函数会清空变量,即使变量已赋值也不行,退出函数时任何out引用的变量都要赋值,ref引用的能够修改,也能够不修改。 

  区别能够参看下面的代码:

using System;

using System.Collections.Generic;

using System.Text;

 

namespace @ref

{   

    class TestApp

    {

        static void outTest(out int x, out int y)

        {//离开这个函数前,必须对xy赋值,否则会报错。

            //y = x;

            //上面这行会报错,因为使用了out后,xy都清空了,需要重新赋值,即使调用函数前赋过值也不行

            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);//ref 关键字去掉 会输出1122

            Console.WriteLine("o={0};p={1}", o, p);          

            Console .ReadLine();

        }

    }   

}