分析 C# 2.0 新特性 -- 范型(Generics)
生活随笔
收集整理的這篇文章主要介紹了
分析 C# 2.0 新特性 -- 范型(Generics)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
分析?C#?2.0?新特性?--?范型(Generics)
作者:梁振[MS-MVP]
?
范型是提高面向對象程序多態性設計衍生的。
1,C#?多態性設計回顧和展望
在引入范型這個概念之前,回顧一下1.0或1.1中關于的Object類型的定義:
Object類型是.NET?Framework中System.Object的一個別名,可以分配任何類型給Object類型的變量。
通過object類型的引入,實現了.NET對于面向對象程序多態設計。
因為Object本身是一個引用類型,是存放在Heap(堆)上的。對于其他引用類型和Object轉換很容易實現。
而值類型和Object類型轉換需要引入兩個用于object類型和值類型轉換概念boxing和unboxing.
(1)boxing?裝包
??將轉換一個值類型到Object類型,
??例如:int?i?=?1;????????????//存儲在棧上
????????object?o?=?(object)?i;//存儲在堆上
??上面的代碼在IL中將會是box?[mscorlib]System.Int32
將Int32和1同時裝入一個Object對象中,結構如下:
object[{Int32}-{1}];//前者表示boxing類型,后者表示其值
(2)unboxing?拆包
將一個已裝包為Obect類型的值類型轉換回值類型
操作分為兩部分組成:
a,首先檢查是否轉換回的類型是裝包的類型,如果不是拋出一個InvalidCastException運行時錯誤.
b,復制Object類型中的值到目標值類型變量;
例如:
int?i?=?1;
??????object?o?=?(object)?i;?//boxing
??????int?j?=?(int)o?????????//unboxing
??????//double?d?=?(double)o?,出現運行時錯誤
通過上面的可以看到在.NET?Framework?1.0?中使用object對象設計的多態性比C++的template(一種基于類似宏的編
譯時替換)執行效率增加了大量的copy的開銷。所以在.NET?Framewrok?2.0中引入范型來提高高面向對象程序多態性
設計。
2,范型概念和特點:
范型的設計是為了解決上面提到過的Object的多態性設計中的兩個問題:
(1),性能上面的,boxing和unboxing需要大量的復制開銷;
(2),安全性上面的,在上面一個例子看到了如果unboxing類型不同會拋出一個InvalidCastException異常;
范型的設計格式是使用<和>封閉其中一個范型參數,例如:
public?class?Stack<T>;
范型的實例化格式是使用需要使用的類型替換<和>封閉其中一個范型參數,例如:
Stack<char>?char_Stack?=?new?Stack<char>();
多范型類定義格式,在<和>封閉多個范型參數,例如:
class?Node<K,T>
對于C++程序員,看上面關于范型的格式很快聯系到了ISO?C++當中的Template;
的確兩者語法上面非常相似,但是兩者的多態性編譯和實現有很大不同.
在C++的Template編譯后,沒有編譯帶有Template的代碼.而是通過一種宏的方式進行的替換過程.
每次使用Template類型,編譯器都會生成一個對應的類型代碼.而不管是否個類型代碼已經使用過了.
在C#2.0中范型是在中間語言(IL)和公共語言運行時(CLR)支持的.
對于值類型:會在JIT編譯時候替換參數類型,如果存在以及編譯特定類型的機器代碼,將直接返回這段代碼.
這樣避免了在ISO?C++中Template可能帶來代碼膨脹.
對于引用類型:會直接在JIT編譯時候替換參數類型.
理解C#?2.0范型是在實現是基于CLR支持的很重要啊,因為.NET的本質是和語言無關的.任何語言最后都是編譯為中
間語言,這樣基于IL和CLR支持的范型可以運用到所有基于CLR實現的語言,例如:Visual?Basic?2005等等.
3,范型和其他類型執行效率對比例子
下面分別是使用Int,Object和范型構造的3個棧的類
?///?<summary>
?///?Int類型實現的棧
?///?</summary>
?class?IntStack
?{
??private?int[]?data;
??private?int?current;
??private?int?length;
??public?IntStack(int?Length)
??{
???length?=?Length;
???current?=?0;
???data?=?new?int[length];
??}
??public?int?Top()
??{
???return?data[current?-?1];
??}
??public?void?Push(int?Data)
??{
???if?(current?<?length)
???{
????data[current++]?=?Data;
???}
??}
??public?void?Pop()
??{
???if?(current?>?0)
???{
????current--;
???}
??}
?}
?///?<summary>
?///?范型的棧
?///?</summary>
?///?<typeparam?name="T">范型</typeparam>
?class?TemplateStack<T>
?{
??private?int?length;
??private?int?current;
??private?T[]?data;
??public?TemplateStack(int?Length)
??{
???current?=?0;
???length?=?Length;
???data?=?new?T[length];
??}
??public?T?Top()
??{
???return?data[current?-?1];
??}
??public?void?Push(T?Data)
??{
???if?(current?<?length)
???{
????data[current++]?=?Data;
???}
??}
??public?void?Pop()
??{
???if?(current?>?0)
???{
????current--;
???}
??}
?}
?///?<summary>
?///?Object的棧
?///?</summary>
?class?ObjectStack
?{
??private?object[]?data;
??private?int?current;
??private?int?length;
??public?ObjectStack(int?Length)
??{
???length?=?Length;
???current?=?0;
???data?=?new?object[length];
??}
??public?object?Top()
??{
???return?data[current-1];
??}
??public?void?Push(object?Data)
??{
???if?(current?<?length)
???{
????data[current++]?=?Data;
???}
??}
??public?void?Pop()
??{
???if?(current?>?0)
???{
????current--;
???}
??}
?}
通過測試直接使用Int的棧和范型構造Int棧的開銷接近.
而比較前面兩個Object每增加一次unboxig開銷是增加的2倍.
4,附錄.NET?2.0?Framework?范型容器列表:
Comparer<T>? Comparer?? 比較
Dictionary<K,T>?? ?HashTable? hash表
LinkedList<T>?????????LinkList?? 鏈表
List<T>???????????????ArrayList? 數組鏈表
Queue<T>??????????????Queue? 隊列
SortedDictionary<K,T>?SortedList 排序鏈表
Stack<T>??????????????Stack? 棧
ICollection<T>??ICollection? 容器接口
IComparable<T>??System.IComparable比較接口
IDictionary<K,T>??IDictionary?? ?字典接口
IEnumerable<T>??IEnumerable? 枚舉接口
IEnumerator<T>??IEnumerator? 跌代接口
IList<T>??IList? 鏈表接口
?
參考資料:
《Design?and?Implementation?of?Generics?for?the?.NET?Common?Language?Runtime》?
??---Andrew?Kennedy?Don?Syme?(Microsoft?Research,?Cambridge,?U.K.)
《An?Introduction?to?C#?Generics》
??---Juval?Lowy?IDesign?(MSDN?Online)
《C#?Programmer's?Reference》
??---MSDN?Library??(MSDN?Online)
作者:梁振[MS-MVP]
?
范型是提高面向對象程序多態性設計衍生的。
1,C#?多態性設計回顧和展望
在引入范型這個概念之前,回顧一下1.0或1.1中關于的Object類型的定義:
Object類型是.NET?Framework中System.Object的一個別名,可以分配任何類型給Object類型的變量。
通過object類型的引入,實現了.NET對于面向對象程序多態設計。
因為Object本身是一個引用類型,是存放在Heap(堆)上的。對于其他引用類型和Object轉換很容易實現。
而值類型和Object類型轉換需要引入兩個用于object類型和值類型轉換概念boxing和unboxing.
(1)boxing?裝包
??將轉換一個值類型到Object類型,
??例如:int?i?=?1;????????????//存儲在棧上
????????object?o?=?(object)?i;//存儲在堆上
??上面的代碼在IL中將會是box?[mscorlib]System.Int32
將Int32和1同時裝入一個Object對象中,結構如下:
object[{Int32}-{1}];//前者表示boxing類型,后者表示其值
(2)unboxing?拆包
將一個已裝包為Obect類型的值類型轉換回值類型
操作分為兩部分組成:
a,首先檢查是否轉換回的類型是裝包的類型,如果不是拋出一個InvalidCastException運行時錯誤.
b,復制Object類型中的值到目標值類型變量;
例如:
int?i?=?1;
??????object?o?=?(object)?i;?//boxing
??????int?j?=?(int)o?????????//unboxing
??????//double?d?=?(double)o?,出現運行時錯誤
通過上面的可以看到在.NET?Framework?1.0?中使用object對象設計的多態性比C++的template(一種基于類似宏的編
譯時替換)執行效率增加了大量的copy的開銷。所以在.NET?Framewrok?2.0中引入范型來提高高面向對象程序多態性
設計。
2,范型概念和特點:
范型的設計是為了解決上面提到過的Object的多態性設計中的兩個問題:
(1),性能上面的,boxing和unboxing需要大量的復制開銷;
(2),安全性上面的,在上面一個例子看到了如果unboxing類型不同會拋出一個InvalidCastException異常;
范型的設計格式是使用<和>封閉其中一個范型參數,例如:
public?class?Stack<T>;
范型的實例化格式是使用需要使用的類型替換<和>封閉其中一個范型參數,例如:
Stack<char>?char_Stack?=?new?Stack<char>();
多范型類定義格式,在<和>封閉多個范型參數,例如:
class?Node<K,T>
對于C++程序員,看上面關于范型的格式很快聯系到了ISO?C++當中的Template;
的確兩者語法上面非常相似,但是兩者的多態性編譯和實現有很大不同.
在C++的Template編譯后,沒有編譯帶有Template的代碼.而是通過一種宏的方式進行的替換過程.
每次使用Template類型,編譯器都會生成一個對應的類型代碼.而不管是否個類型代碼已經使用過了.
在C#2.0中范型是在中間語言(IL)和公共語言運行時(CLR)支持的.
對于值類型:會在JIT編譯時候替換參數類型,如果存在以及編譯特定類型的機器代碼,將直接返回這段代碼.
這樣避免了在ISO?C++中Template可能帶來代碼膨脹.
對于引用類型:會直接在JIT編譯時候替換參數類型.
理解C#?2.0范型是在實現是基于CLR支持的很重要啊,因為.NET的本質是和語言無關的.任何語言最后都是編譯為中
間語言,這樣基于IL和CLR支持的范型可以運用到所有基于CLR實現的語言,例如:Visual?Basic?2005等等.
3,范型和其他類型執行效率對比例子
下面分別是使用Int,Object和范型構造的3個棧的類
?///?<summary>
?///?Int類型實現的棧
?///?</summary>
?class?IntStack
?{
??private?int[]?data;
??private?int?current;
??private?int?length;
??public?IntStack(int?Length)
??{
???length?=?Length;
???current?=?0;
???data?=?new?int[length];
??}
??public?int?Top()
??{
???return?data[current?-?1];
??}
??public?void?Push(int?Data)
??{
???if?(current?<?length)
???{
????data[current++]?=?Data;
???}
??}
??public?void?Pop()
??{
???if?(current?>?0)
???{
????current--;
???}
??}
?}
?///?<summary>
?///?范型的棧
?///?</summary>
?///?<typeparam?name="T">范型</typeparam>
?class?TemplateStack<T>
?{
??private?int?length;
??private?int?current;
??private?T[]?data;
??public?TemplateStack(int?Length)
??{
???current?=?0;
???length?=?Length;
???data?=?new?T[length];
??}
??public?T?Top()
??{
???return?data[current?-?1];
??}
??public?void?Push(T?Data)
??{
???if?(current?<?length)
???{
????data[current++]?=?Data;
???}
??}
??public?void?Pop()
??{
???if?(current?>?0)
???{
????current--;
???}
??}
?}
?///?<summary>
?///?Object的棧
?///?</summary>
?class?ObjectStack
?{
??private?object[]?data;
??private?int?current;
??private?int?length;
??public?ObjectStack(int?Length)
??{
???length?=?Length;
???current?=?0;
???data?=?new?object[length];
??}
??public?object?Top()
??{
???return?data[current-1];
??}
??public?void?Push(object?Data)
??{
???if?(current?<?length)
???{
????data[current++]?=?Data;
???}
??}
??public?void?Pop()
??{
???if?(current?>?0)
???{
????current--;
???}
??}
?}
通過測試直接使用Int的棧和范型構造Int棧的開銷接近.
而比較前面兩個Object每增加一次unboxig開銷是增加的2倍.
4,附錄.NET?2.0?Framework?范型容器列表:
Comparer<T>? Comparer?? 比較
Dictionary<K,T>?? ?HashTable? hash表
LinkedList<T>?????????LinkList?? 鏈表
List<T>???????????????ArrayList? 數組鏈表
Queue<T>??????????????Queue? 隊列
SortedDictionary<K,T>?SortedList 排序鏈表
Stack<T>??????????????Stack? 棧
ICollection<T>??ICollection? 容器接口
IComparable<T>??System.IComparable比較接口
IDictionary<K,T>??IDictionary?? ?字典接口
IEnumerable<T>??IEnumerable? 枚舉接口
IEnumerator<T>??IEnumerator? 跌代接口
IList<T>??IList? 鏈表接口
?
參考資料:
《Design?and?Implementation?of?Generics?for?the?.NET?Common?Language?Runtime》?
??---Andrew?Kennedy?Don?Syme?(Microsoft?Research,?Cambridge,?U.K.)
《An?Introduction?to?C#?Generics》
??---Juval?Lowy?IDesign?(MSDN?Online)
《C#?Programmer's?Reference》
??---MSDN?Library??(MSDN?Online)
總結
以上是生活随笔為你收集整理的分析 C# 2.0 新特性 -- 范型(Generics)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 又一游戏大盗(完美世界、跑跑等)SysI
- 下一篇: 如何配置三层交换机创建VLAN 3