自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

C#引用類型深入剖析

開發(fā) 后端
本文介紹了c#引用類型和值類型的區(qū)別的第一部分,從概念上看,值類型直接存儲其值,而引用類型存儲對其值的引用。這兩種類型存儲在內(nèi)存的不同地方。

C#有很多值得學(xué)習(xí)的地方,這里我們主要介紹C#引用類型,包括介紹C#引用類型和值類型的區(qū)別——通用類型系統(tǒng)等方面。

從概念上看,值類型直接存儲其值,而引用類型存儲對其值的引用。這兩種類型存儲在內(nèi)存的不同地方。在C#中,我們必須在設(shè)計類型的時候就決定類型實例的行為。這種決定非常重要,用《CLR via C#》作者Jeffrey Richter的話來說,“不理解引用類型和值類型區(qū)別的程序員將會給代碼引入詭異的bug和性能問題(I believe that a developer who misunderstands the difference between reference types and value types will introduce subtle bugs and performance issues into their code.)”。這就要求我們正確理解和使用值類型和引用類型。

1. 通用類型系統(tǒng)

2. 值類型

3. 引用類型

4. 值類型和引用類型在內(nèi)存中的部署

4.1 數(shù)組在內(nèi)存中的部署

4.2 值類型和引用類型的嵌套

5. 正確使用值類型和引用類型

5.1 辨明值類型和引用類型的使用場合

5.2 將值類型盡可能實現(xiàn)為具有常量性和原子性的類型

5.3 確保0為值類型的有效狀態(tài)

5.4 盡量減少裝箱和拆箱

6. 總結(jié)

7. 參考

C#引用類型和值類型的區(qū)別——通用類型系統(tǒng)

C#中,變量是值還是引用僅取決于其數(shù)據(jù)類型。

C#的基本數(shù)據(jù)類型都以平臺無關(guān)的方式來定義。C#的預(yù)定義類型并沒有內(nèi)置于語言中,而是內(nèi)置于.NET Framework中。.NET使用通用類型系統(tǒng)(CTS)定義了可以在中間語言(IL)中使用的預(yù)定義數(shù)據(jù)類型,所有面向.NET的語言都最終被編譯為IL,即編譯為基于CTS類型的代碼。

例如,在C#中聲明一個int變量時,聲明的實際上是CTS中System.Int32的一個實例。這具有重要的意義:

確保IL上的強制類型安全;

實現(xiàn)了不同.NET語言的互操作性;

所有的數(shù)據(jù)類型都是對象。它們可以有方法,屬性,等。例如:

  1. int i;  
  2. i = 1;  
  3. string s;  
  4. s = i.ToString(); 

MSDN的這張圖說明了CTS中各個類型是如何相關(guān)的。注意,類型的實例可以只是值類型或自描述類型,即使這些類型有子類別也是如此。

C#引用類型和值類型的區(qū)別——值類型

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

結(jié)構(gòu)體:struct(直接派生于System.ValueType);

數(shù)值類型:

整型: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);

用于財務(wù)計算的高精度decimal型:decimal(System.Decimal)。

bool型:bool(System.Boolean的別名);

用戶定義的結(jié)構(gòu)體(派生于System.ValueType)。

枚舉:enum(派生于System.Enum);

可空類型(派生于System.Nullable< T>泛型結(jié)構(gòu)體,T?實際上是System.Nullable< T>的別名)。

每種值類型均有一個隱式的默認(rèn)構(gòu)造函數(shù)來初始化該類型的默認(rèn)值。例如:

  1. int i = new int(); 

等價于:

  1. Int32 i = new Int32(); 

等價于:

  1. int i = 0; 

等價于:

  1. Int32 i = 0; 

使用new運算符時,將調(diào)用特定類型的默認(rèn)構(gòu)造函數(shù)并對變量賦以默認(rèn)值。在上例中,默認(rèn)構(gòu)造函數(shù)將值0賦給了i。MSDN上有完整的默認(rèn)值表。

關(guān)于int和Int32的細(xì)節(jié),在我的另一篇文章中有詳細(xì)解釋:《理解C#中的System.Int32和int》。

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

值得注意的是,System.ValueType直接派生于System.Object。即System.ValueType本身是一個類類型,而不是值類型。其關(guān)鍵在于ValueType重寫了Equals()方法,從而對值類型按照實例的值來比較,而不是引用地址來比較。

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

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

C#引用類型和值類型的區(qū)別——引用類型

C#有以下一些引用類型:

數(shù)組(派生于System.Array)

用戶用定義的以下類型:

類:class(派生于System.Object);

接口:interface(接口不是一個“東西”,所以不存在派生于何處的問題。Anders在《C# Programming Language》中說,接口只是表示一種約定[contract]);

委托:delegate(派生于System.Delegate)。

object(System.Object的別名);

字符串:string(System.String的別名)。

可以看出:

引用類型與值類型相同的是,結(jié)構(gòu)體也可以實現(xiàn)接口;

引用類型可以派生出新的類型,而值類型不能;

引用類型可以包含null值,值類型不能(可空類型功能允許將 null 賦給值類型);

引用類型變量的賦值只復(fù)制對對象的引用,而不復(fù)制對象本身。而將一個值類型變量賦給另一個值類型變量時,將復(fù)制包含的值。

對于***一條,經(jīng)?;煜氖莝tring。我曾經(jīng)在一本書的一個早期版本上看到String變量比string變量效率高;我還經(jīng)常聽說String是引用類型,string是值類型,等等。例如:

  1. string s1 = "Hello, ";  
  2. string s2 = "world!";  
  3. string s3 = s1 + s2;//s3 is "Hello, world!" 

這確實看起來像一個值類型的賦值。再如:

  1. string s1 = "a";  
  2. string s2 = s1;  
  3. s1 = "b";//s2 is still "a" 

改變s1的值對s2沒有影響。這更使string看起來像值類型。實際上,這是運算符重載的結(jié)果,當(dāng)s1被改變時,.NET在托管堆上為s1重新分配了內(nèi)存。這樣的目的,是為了將做為引用類型的string實現(xiàn)為通常語義下的字符串。

【編輯推薦】

  1. 解密C#-SQLite是如何移植的
  2. 看看如何透過JavaScript調(diào)用C#函數(shù)
  3. 淺析C#事件注冊和注銷
  4. 示例:C#通過AMO對象瀏覽SQL SERVER 2005 SSAS
  5. C#隱藏窗口的幾種方法
責(zé)任編輯:book05 來源: hi.baidu
相關(guān)推薦

2009-09-11 11:17:04

C#引用類型

2009-09-02 18:14:33

C# WebClien

2009-08-14 17:09:48

C#引用類型

2009-09-02 13:36:58

C#實現(xiàn)多個接口

2009-09-04 17:56:22

C#刪除數(shù)據(jù)

2009-08-03 17:51:43

C#引用類型

2009-08-06 10:14:15

C#引用類型數(shù)組

2009-09-03 16:55:58

C#引用類型

2009-09-03 15:03:27

C#實現(xiàn)AOP微型框架

2009-09-03 17:42:07

C#開發(fā)CF藍(lán)牙模塊

2009-08-19 16:39:44

C#值類型C#引用類型

2009-08-26 14:05:19

C#值類型和引用類型

2009-08-27 16:39:26

C# String類型

2009-09-04 17:49:34

C#連接數(shù)據(jù)庫

2011-06-08 13:03:52

C#值類型引用類型

2022-01-12 09:08:37

索引JavaReference對象

2013-05-23 17:21:16

C#

2009-10-22 18:41:49

CLR VIA C#教

2009-09-07 14:29:52

C# ServiceC

2009-08-27 17:14:36

C# Socket
點贊
收藏

51CTO技術(shù)棧公眾號