C#中使用ref和out一點認識

來源:互聯網
上載者:User

首先,如果不使用這兩個關鍵字,那是什麼樣 呢?

看下面的例子:

using System;
  class Test
  {
      static void Swap(ref int x, ref int y)
      {
          int temp = x;
          x = y;
          y = temp;
      }
      static void Swap(int x,int y)
      {
          int temp = x;
          x = y;
          y = temp;
      }
      static void Main()
      {
          int i = 1, j = 2;
          Swap(ref i, ref j);
          Console.WriteLine("i = {0}, j = {1}", i, j);
          Swap(i,j);
          Console.WriteLine("i = {0}, j = {1}", i, j);
      }
  }
  
    程式經編譯後執行輸出:
  
  i = 2, j = 1
  i = 2, j = 1

這是csdn的一篇文章上的例子.其實如果放在一起,並不能很容易的看出使用ref和不使用ref的區別.

分開看,就很明顯了.

使用ref:

using System;
  class Test
  {
      static void Swap(ref int x, ref int y)
      {
          int temp = x;
          x = y;
          y = temp;
      }

      
      static void Main()
      {
          int i = 1, j = 2;
          Swap(ref i, ref j);
          Console.WriteLine("i = {0}, j = {1}", i, j);           
      }
  }
  
    程式經編譯後執行輸出:
  
  i = 2, j = 1

不使用:

using System;
  class Test
  {       
      static void Swap(int x,int y)
      {
          int temp = x;
          x = y;
          y = temp;
      }
      static void Main()
      {
          int i = 1, j = 2;
          Swap(i,j);
          Console.WriteLine("i = {0}, j = {1}", i, j);
      }
  }
  
    程式經編譯後執行輸出:

          i = 1, j = 2;

比較這兩個裡子很明顯,使用了ref關鍵字的函數調用以後,i和j的值變化了.而沒有使用ref的卻沒有變,為什麼呢?

請看下面這段話:

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

          所以我們可以看出,平時我們寫的函數參數是傳值參數(傳值參數無需額外的修飾符),不論他是實值型別還是參考型別.你可以試這個例子(這個例子是對"不論他是實值型別還是參考型別"這句話,):

using System;
  class Test
  {       
      static void Swap(string x,string y)
      {
          string temp = x;
          x = y;
          y = temp;
      }
      static void Main()
      {
          string i = "1", j = "2";
          Swap(i,j);
          Console.WriteLine("i = {0}, j = {1}", i, j);
      }
  }
  
    程式經編譯後執行輸出:

          i = "1", j = "2";

          注意:string類型是參考型別.

i,j的值並沒有改變,說明參考型別作為函數參數時,只要不加ref或者out,那他仍然是傳值參數(我一直以為實值型別作為函數參數時是傳值參數,而參考型別作為函數參數時是傳址參數).

.net架構程式設計(修訂版)上有這樣一句話:ref和out的區別是參數的初始化和參數返回,

可是這裡說out是輸出參數,那加out是傳址參數嗎?要不,怎麼也會變呢(應該也是吧,可能他只是一個名字,可以理解成輸出參數也是傳址參數)?

using System;
  class Test
  {
      static void Swap(out int x, out int y)
      {
          int temp = x;
          x = y;
          y = temp;
      }

      
      static void Main()
      {
          int i = 1, j = 2;
          Swap(out i, out j);
          Console.WriteLine("i = {0}, j = {1}", i, j);           
      }
  }

程式經編譯後執行輸出:
  
  i = 2, j = 1

總結:傳值參數傳遞的是調用參數的一份拷貝,而傳址參數傳遞的是調用參數的記憶體位址,該參數在方法內外指向的是同一個儲存位置.

這句話可以這樣說更加明白:傳值參數傳遞的是調用參數的拷貝的地址,該參數在方法內外指向的不是是同一個儲存位置,而傳址參數傳遞的是調用參數的記憶體位址,該參數在方法內外指向的是同一個儲存位置,

理解這句話,自然明白為什麼會變化或者為什麼不變化.

以上是個人的一點理解,肯定有不妥之處,請批評指出.

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.