C# 實值型別和參考型別 以及作為方法參數的區別

來源:互聯網
上載者:User
在C#中有兩種類型的資料,一種是實值型別資料,一種是參考型別資料。在編碼的時候區分這兩種類型資料,可以避免一些細小的編碼錯誤。
      首先說說什麼類型是實值型別,例如:int、float、bool之類的基礎類型,以及用struct定義的類型,如:DateTime。除此外,如string,數組,以及用class定義的類型等都是參考型別。對於C#來說,很難羅列出所有類型進行一一分別,這需要自己在編碼過程中進行分析總結。為了更好地說明兩種類型之間的區別,借用如下的表格來說明。
實值型別 參考型別
記憶體配置地點 分配在棧中 分配在堆中
效率 效率高,不需要地址轉換 效率低,需要進行地址轉換
記憶體回收 使用完後,立即回收 使用完後,不是立即回收,等待GC回收
賦值操作 進行複製,建立一個同值新對象 只是對原有對象的引用
函數參數與傳回值 是對象的複製 是原有對象的引用,並不產生新的對象
類型擴充 不易擴充 容易擴充,方便與類型擴充

過如上細緻對比,大家對於實值型別和參考型別有個清楚的概念。

  不過,無論是對於實值型別還是參考型別來說,對於其作為函數參數或者傳回值的時候,都是容易犯錯誤的地方。

  對於實值型別來說,當其作為函數參數的時候,希望在函數中被修改,那麼直接如下操作是不能被修改的。

public void Increment( int i )
{
  i++;
}

  要想在函數中對傳進去的參數做真正的修改,需要藉助於ref這個關鍵字,那麼正確的形式如下。

public void Increment( ref int i )
{
 i++;
}

  也就是說,如果需要在函數中對實值型別參數進行修改,需要用ref或者out進行標識才能真正實現。

那麼參考型別又是如何那?

其實這個問題很容易理解,首先在C#中傳遞方法參數預設是“值拷貝”模式,也就是說對於實值型別(ValueType)變數直接拷貝一份,而對於參考型別則拷貝一個指向同一對象的引用副本傳遞給方法,因此即使不使用ref關鍵字,我們也可以在方法內部改變該引用所指向對象的內部狀態,但是某些時候我們需要在方法內部建立一個新的對象執行個體,並使得原有引用指向這個新的對象。那麼問題就來了,由於現在存在兩個引用,我們改變的只是傳遞到方法的引用副本,而該副本在超出方法範圍後既失去作用,而原有的引用依然指向原有對象。因此我們需要使用ref關鍵字,那麼傳遞給方法的不再是引用副本,而是引用本身。我們就可以改變原有引用對象執行個體了。

public class Data
  {
    public int i = 10;
  }

  public class Class1
  {
    public static void Test1(Data d)
    {
      // 參數d只是一個引用副本,和原引用變數d同時指向同一個對象,因此都可以修改該對象的狀態。
      d.i = 100;
    }

    public static void Test2(Data d)
    {
      // 建立新的Data對象,並將參數d指向它。此時參數d和原有引用d分別指向2個不同的Data對象,因此
      // 當超出Test方法作用範圍時,參數d和其引用的對象將失去引用,等待GC回收。
      d = new Data();
      d.i = 200;
    }

    public static void Test3(ref Data d)
    {
      // 由於使用ref關鍵字,因此此處的參數d和原變數d為同一引用,並沒有棄置站台,所以建立新的Data
      // 對象是可行的。
      d = new Data();
      d.i = 300;
    }

    public static void Main(string[] args)
    {
      Data d = new Data();
      Console.WriteLine(d.i); // 10

      Test1(d);
      Console.WriteLine(d.i); // 100

      Test2(d);
      Console.WriteLine(d.i); // 100

      Test3(ref d);
      Console.WriteLine(d.i); // 300
    }
  }

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.