【C#】數組、集合、泛型集合的區別與聯繫

From:http://topic.csdn.net/u/20111225/11/e3f37d75-a035-47de-bf7a-1b5106e08846.html

【數組】

  C#數組是個很重要的概念,在C#類庫中,它屬於基本常用的類型,和int,string等是一級別的,是C#最基礎、最核心的部分,它是相同類型的一組集合,當然,它也是安全的;但數組確實也比較奇怪,它到底屬於什麼類型?比如int[] a,A[] a1;確實找不到a或a1的類型定義,即使在CIL中也無此定義,如果用a.GetType(),你得到是System.int32[]----這不純屬扯淡嘛,這種類型找的着嗎?

  但有兩點需要注意:其一,數組也是一個對象,它派生於抽象類Array;其二,數組對象的實例化和C#中其它任何引用類型的實例化都不相同,引用類型是.newobj,而數組是.newarr指令。

  PS,關於第二點:

  源碼:

    public class Prime
    {
        class SampleClass { }
        class Program{
            static void Main(string[] args){
                SampleClass sc = new SampleClass();
                int[] x = new int[2] { 0, 0 };
            }
        }
    }

  彙編代碼:

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       17 (0x11)
  .maxstack  1
  .locals init ([0] class Test.Prime/SampleClass sc,
           [1] int32[] x,
           [2] int32[] CS$0$0000)
  IL_0000:  nop
  IL_0001:  newobj    instance void Test.Prime/SampleClass::.ctor()
  IL_0006:  stloc.0
  IL_0007:  ldc.i4.2
  IL_0008:  newarr     [mscorlib]System.Int32
  IL_000d:  stloc.2
  IL_000e:  ldloc.2
  IL_000f:  stloc.1
  IL_0010:  ret
} // end of method Program::Main

這兩點很重要,我們可以推測下數組對象的類型到底是什麼,諸如C#編譯器遇到int[],A[],B[]……時,應該映射成各個繼承Array的子類,然後纔是實例化,這乍一看有理,再想想就可笑了,IL只有個.newarr指令;如果我們要用C#設計一個高效可重用的數組類,我們怎麼辦?這幾乎是不可能的。其實數組很容易理解,剛纔的newarr就說明了一切,C#中的數組操作已經固化成一個特定的指令了,這樣它就和其它類型不一樣了,顯得低級化了;實際看來,C#數組和泛型的效率至少不低於C/C++及STL,它們不是被面向對象化了,而是虛擬了面向對象,這樣看來,它們的實現不是面向對象的封裝,至少是C/C++級別的特定安全實現,甚至是用匯編或機器指令寫的,如此看來,再索求數組和泛型是什麼類型時倒顯得有些荒唐了,我們姑且就認爲它是面向對象化了,當然看到的都是假象,這些假象中又最重要的一點---這個所謂的假數組對象也有一個假的索引器,這樣看起來和真實對象的索引器就是一個概念。

  C#數組對象的特點就是虛擬成了面向對象,有了索引器概念,是面向對象的,是安全的,又是很高效的,當然也是最不靈活的!


【集合】

  由於要靈活,集合就產生了,它是做爲一個通用的算法產生的,有ArrayList,Stack….提供了常用的容器,這種通用性是用萬能的object實現的;特點就是:可以裝各個類型(這違背了數組單一化原則,除非迫不得已,千萬不要這麼做),存在類型不安全因素,性能差勁!針對此,出現了自定義的加強版的集合-----強類型集合,它解決了安全性,但是通用性差,性能低。由此可年,通吃各種類型到成了唯一的特點,除非迫不得已,不要用。


【泛型集合】

  於是,除了有靈活性和通用性特點外,安全和高效的集合便誕生了,同時,泛型的概念也推廣了。在自定義泛型集合中,引出了約束佔位符類型的語法規則,要了解一下!

  泛型思考,泛型是一種思想,主要體現在算法上,它最大特點就是在不犧牲效率的前提下實現算法的通用性-----真正實現代碼的重用,其抽象級別要比面向對象高;泛型是面向算法(過程)編程,脫離數據,實現算法(模式)的重用性;面向對象是面向大型軟件的編程,封裝數據和算法,通過繼承和組合實現組件(代碼)的可重用性。

  泛型類、泛型接口、泛型代理、泛型方法:
  泛型類
相比類而言,更抽象,應該體現算法和數據容器的作用,除此以外,慎用泛型,它並不是萬能的!
  泛型接口相比接口而言,更體現接口約定的抽象性。
  泛型代理更能體現方法類型的抽象性。
  泛型方法更能體現算法的抽象性,泛型方法能實現的算法,一定能用函數重載實現,而函數的重載不一定能用泛型方法實現,最重要的是泛型方法內不允許有佔位符類型參與各種運算操作,這大大限制了泛型的功能。

  總結:泛型類型是定義時用佔位符, 佔位符只能出現在泛型類型定義內或泛型方法內。

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