C#中ref和out的區別

GeekWay發表於2013-01-15

C#中ref和out的區別

ref和out這兩個關鍵字都能夠提供相似的功效,其作用也很像C中的指標變數。它們的區別是:


1、使用ref型引數時,傳入的引數必須先被初始化。對out而言,必須在方法中對其完成初始化。
如:

static void Main(string[] args)
        {
            int a = 5;
            int b =10;
            squareRef(ref a);
            squareOut(out b);
            Console.WriteLine("The a in the Main is: " + a);
            Console.WriteLine("The b in the Main is: " + b);

        }
        static void squareRef(ref int x)
        {
            x = x * x;  //x的值引用是a中的值
            Console.WriteLine("The x in the squareRef is: " + x);
        }
        static void squareOut(out int y)
        {
            y = 10; //此句不可刪,因為是out型賦值,y的改變同時影響到此函式外的b
            y = y * y;
            Console.WriteLine("The y in the squareOut is: " + y);
        }


2、使用ref和out時,在方法的引數和執行方法時,都要加Ref或Out關鍵字。以滿足匹配。


3、out適合用在需要返回多個值(注:不是“多個返回值”)的地方,而ref則用在需要被呼叫的方法修改呼叫者的引用的時候。

        static void testOut(out int a, out int b, out string c, out bool d)
        {
            a = 1;
            b = 2;
            c = "我是第三個引數";
            d = true;
        }
        public static void Main()
        {
            int a, b;
            string c;
            bool d;

            testOut(out a, out b, out c, out d);
            //經過執行方法testOut(),相當於返回了a,b,c,d四個引數,也就是說out適合用於返回多個引數的情況

            Console.Write("{0},{1},{2},{3}", a, b, c, d.ToString());
            Console.Read();

        }
   



擴充:

注:在C#中,方法的引數傳遞有四種型別:傳值(by value),傳址(by reference),輸出引數(by output),陣列引數(by array)。傳值引數無需額外的修飾符,傳址引數需要修飾符ref,輸出引數需要修飾符out,陣列引數需要修飾符params。傳值引數在方法呼叫過程中如果改變了引數的值,那麼傳入方法的引數在方法呼叫完成以後並不因此而改變,而是保留原來傳入時的值。傳址引數恰恰相反,如果方法呼叫過程改變了引數的值,那麼傳入方法的引數在呼叫完成以後也隨之改變。實際上從名稱上我們可以清楚地看出兩者的含義--傳值引數傳遞的是呼叫引數的一份拷貝,而傳址引數傳遞的是呼叫引數的記憶體地址,該引數在方法內外指向的是同一個儲存位置。


方法引數上的 ref 方法引數關鍵字使方法引用傳遞到方法的同一個變數。當控制傳遞迴呼叫方法時,在方法中對引數所做的任何更改都將反映在該變數中。


若要使用 ref 引數,必須將引數作為 ref 引數顯式傳遞到方法。ref 引數的值被傳遞到 ref 引數。


傳遞到 ref 引數的引數必須最先初始化。將此方法與 out 引數相比,後者的引數在傳遞到 out 引數之前不必顯式初始化。


屬性不是變數,不能作為 ref 引數傳遞。


如果兩種方法的宣告僅在它們對 ref 的使用方面不同,則將出現過載。但是,無法定義僅在 ref 和 out 方面不同的過載。


out


方法引數上的 out 方法引數關鍵字使方法引用傳遞到方法的同一個變數。當控制傳遞迴呼叫方法時,在方法中對引數所做的任何更改都將反映在該變數中。


當希望方法返回多個值時,宣告 out 方法非常有用。使用 out 引數的方法仍然可以返回一個值。一個方法可以有一個以上的 out 引數。


若要使用 out 引數,必須將引數作為 out 引數顯式傳遞到方法。out 引數的值不會傳遞到 out 引數。


不必初始化作為 out 引數傳遞的變數。然而,必須在方法返回之前為 out 引數賦值。


屬性不是變數,不能作為 out 引數傳遞。




網上有很多文章說ref 只傳值,out傳地址等等這種說法,好像不是非常的準確。以下是我做的例項程式碼,大家可以去試試:


 public int  RefValue(int i,ref int j)
        {
            int k = j;
            j =222;
            return i+k;
        }


     
        public int OutValue(int i, out int j)
        {
            j = 222;
            return i + j;
        }


        private void cmdRef_Click(object sender, EventArgs e)
        {
            int m = 0;
            MessageBox.Show(RefValue(1, ref m).ToString());
            MessageBox.Show(m.ToString());
        }


        private void cmdOut_Click(object sender, EventArgs e)
        {
            int m;
            MessageBox.Show(OutValue(1, out m).ToString());
            MessageBox.Show(m.ToString());
        }


相關文章