【傻傻分不清楚】C#值類型、引用類型

1.包含的數據類型

1.1值類型

C#的所有值類型均隱式派生自System.ValueType

  • 結構體:struct(直接派生於System.ValueType);
    • 數值類型:
      • 整 型:sbyte(System.SByte的別名),short(System.Int16),int(System.Int32),long (System.Int64),byte(System.Byte),ushort(System.UInt16),uint (System.UInt32),ulong(System.UInt64),char(System.Char);
      • 浮點型:float(System.Single),double(System.Double);
      • 用於財務計算的高精度decimal型:decimal(System.Decimal)。
    • bool型:bool(System.Boolean的別名);
    • 用戶定義的結構體(派生於System.ValueType)。
  • 枚舉:enum(派生於System.Enum);
  • 可空類型(派生於System.Nullable<T>泛型結構體,T?實際上是System.Nullable<T>的別名)。
值類型實例通常分配在線程的堆棧(stack)上,並且不包含任何指向實例數據的指針,因爲變量本身就包含了其實例數據。

每種值類型均有一個隱式的默認構造函數來初始化該類型的默認值。

所有的值類型都是密封(seal)的,所以無法派生出新的值類型。

可以用Type.IsValueType屬性來判斷一個類型是否爲值類型:

TestType testType = new TestType ();
if (testTypetype.GetType().IsValueType)
{
Console.WriteLine("{0} is value type.", testType.ToString());
}

1.2引用類型

引用類型繼承System.Object

  • 數組(派生於System.Array)
  • 用戶用定義的以下類型:
    • 類:class(派生於System.Object);
    • 接口:interface(接口不是一個“東西”,所以不存在派生於何處的問題。Anders在《C# Programming Language》中說,接口只是表示一種約定[contract]);
    • 委託:delegate(派生於System.Delegate)。
  • object(System.Object的別名);
  • 字符串:string(System.String的別名)。

1.3在數據類型的區別

  • 引用類型可以派生出新的類型,而值類型不能;
  • 引用類型可以包含null值,值類型不能(可空類型功能允許將 null 賦給值類型);
  • 引用類型變量的賦值只複製對對象的引用,而不復制對象本身。而將一個值類型變量賦給另一個值類型變量時,將複製包含的值

2.內存分配區別

  • 值類型變量做爲局部變量時,該實例將被創建在堆棧上;而如果值類型變量作爲類型的成員變量時,它將作爲類型實例數據的一部分,同該類型的其他字段都保存在託管堆上,將在接下來的嵌套結構部分來詳細說明問題。

  • 引用類型變量數據保存在託管堆上,但是根據實例的大小有所區別,如下:如果實例的大小小於85000Byte時,則該實例將創建在GC堆上;而當實例大小大於等於85000byte時,則該實例創建在LOH(Large Object Heap)堆上。

關於內存分佈,準備用一篇文章專門來探討。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章