久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

.NET 2.0 基礎類庫中的范型——范型集合(轉與 www.chinacs.net )

 快樂學習 2007-06-09

毫無疑問,,范型最典型的應用莫過于范型集合了,。在 .NET 2.0 中提供了已有集合類和接口的范型版本,,它們位于 System.Collections.Generic 命名空間中,。

.NET 2.0 中新的范型集合類并不是簡單的在已有非范型集合類的設計上多加了個范型參數(shù) T 而已,。新的范型集合類的設計充分吸收了已有設計中的合理之處并摒棄了一些不甚合理之處,同時引入了新的針對范型的設計,。所以,,新的范型類和接口的設計應該更加合理和有效,不過 .NET 程序員則需要花些時間學習新的設計并了解與已有設計有什么樣的不同,,以及在將代碼從非范型集合移植到范型集合時可能會出現(xiàn)的兼容性問題,。

下面是范型集合和已有非范型集合的對照表(不全):

 

非范型接口

范型接口

非范型類

范型

IEnumerator

IEnumerator<T>

ArrayList

List<T>

IEnumerable

IEnumerable<T>

Stack

Stack<T>

ICollection

ICollection<T>

Queue

Queue<T>

IList

IList<T>

DictionaryEntry

KeyValuePair<K, V>

IDictionary

IDictionary<T>

Hashtable

Dictionary<K, V>

IComparable

IComparable<T>

Comparer

Comparer<T>

IComparer

IComparer<T>

 

可以看到,部分類的名字做了修改,,例如 ArrayList 現(xiàn)在改為 List<T>,,Hashtable 改為 Dictionary<K, V>,,DictionaryEntry 改為 KeyValuePair<K, V> 等等。這樣的命名當然更加合理(因為 IList<T> 是接口,,List<T> 是對應的具體類,;同樣 IDictionary<K, V> 是接口, Dictionary<K, V> 是對應的具體類,;而 KeyValuePair<K, V> 顯然比 DictionaryEntry 更加容易理解和記憶),,但對已經(jīng)習慣了以前的命名的程序員來說可能一開始會有點找不找北的感覺。

前面說過,,新的范型集合接口/類和以前的非范型版本相比有較大的設計改變,,下面我們來看看這些變化。

IEnumerator<T>

IEnumerator/IEnumerator<T> 接口允許對一個集合進行遍歷,,主要用在 .NET 編程語言的遍歷語句中,,例如 C# foreach 語句。用戶代碼通常不直接使用這個接口,。IEnumerator<T> 和非范型版本 IEnumerator 相比去掉了 Reset 方法,。這可能是出于以下考慮:

l IEnumerator<T> 接口主要設計用于支持諸如 foreach 這樣的語句,而這些地方用不到 Reset 方法,。去掉 Reset 方法使得設計更加簡化并降低了實現(xiàn)該接口的難度,。如果調用者需要類似 Reset 的功能,可以重新獲取一個枚舉器(例如通過調用 GetEnumerator 方法),。

l C# 2.0 Iterators 提供了自動生成枚舉器的方法,,編譯器自動為指定的類實現(xiàn) IEnumerator 接口和 IEnumerator<T> 接口。而對IEnumerator 接口的 Reset 方法的實現(xiàn)只是簡單的拋出 System.NotSupportedException 異常,。所以在 IEnumerator<T> 的設計中移去 Reset 方法顯得非常自然和合理,。

ICollection<T>

ICollection<T> 接口的設計和非范型版本 ICollection 相比改變很大。ICollection 接口的最初設計意圖是支持復制集合元素(通過 Count 屬性和 CopyTo 方法),,以及支持同步訪問模式(通過 IsSynchronized 屬性和 SyncRoot 屬性),。ICollection<T> 的設計保留了對復制集合元素的支持,但是摒棄了對同步訪問模式的支持,,這是因為實踐證明 ICollection 的同步訪問模式是讓人困惑和低效的,。不少剛學 .NET 的程序員一開始搞不懂 SyncRoot 是個什么東東,有什么用,。另外,,從性能和邏輯上考慮,何時鎖定集合應該由調用者決定,,而不是由實現(xiàn)者決定,。所以總的來說 IsSynchronized SyncRoot 不是很理想的設計。因此,ICollection<T> 沒有 IsSynchronized 屬性和 SyncRoot 屬性,。

除此之外,,ICollection<T> 還增加了一些新的屬性和方法,它們讓 ICollection<T> 接口變得更加有用,。這些屬性和方法事實上是從 IList IDictionary 的共同屬性和方法移植過來的,,包括:

l IsReadOnly,用于判斷集合是否是只讀的,。

l Add/Remove/Clear,,用于對集合元素進行管理。這些方法對列表和字典都是有效的,。

l Contains,,用于判斷集合中是否包含指定的值。

另外,,對于一些不需要更改集合的使用情景來說,,提供一個類似 IReadOnlyCollection<T> 這樣的接口可能會有意義,它只需要支持 Count 屬性,,CopyTo 方法和 Contains 方法即可,。然而微軟并沒有采用這樣的設計,主要理由是為了使基本集合接口盡量簡單和易用,。微軟的建議是程序員需要的話自己定義這樣的接口,。

IList<T> List<T>

剛才提到,IList<T> 相對于 IList 的變化是通用的屬性和方法被移植入 ICollection<T> 了,,僅剩下對列表有效的基于索引訪問的屬性和方法,。

List<T> 相對 ArrayList 來講也做了很大的設計改變。做出這些改變的主要考慮是性能,,因為動態(tài)數(shù)組是 .NET 程序使用的最基本的數(shù)據(jù)結構之一,,它的性能影響到應用程序的全局。例如,,以前 ArrayList 默認的 Capacity 16,,而 List<T> 的默認 Capacity 4,這樣可以盡量減小應用程序的工作集,。另外,,List<T> 的方法不是虛擬方法(ArrayList 的方法是虛擬方法),這樣可以利用函數(shù)內(nèi)聯(lián)來提高性能(虛函數(shù)不可以被內(nèi)聯(lián)),。List<T> 也不支持問題多多的 Synchronized 同步訪問模式,。

List<T> 相比 ArrayList 增加的一個重要特性則是對 Functional Programming 的支持,。我們將在 Functional Programming 部分介紹這一新特性,。

IDictionary<K, V> Dictionary<K, V>

IDictionary<K, V> Dictionary<K, V> 相比非范型版本一個很大的變化是當指定的鍵不存在時索引器的處理邏輯。對 IDictionary Hashtable 來說,,值的存儲類型是 object,,當鍵不存在時,,索引器將返回 null,當鍵存在而對應值為 null 的話也返回 null(設計者可能認為調用者通常關心的是值是不是有效,,而不是區(qū)分這兩種情況),。然而,對于范型版本來說,,因為存儲的可能是值類型,,所以不可以返回 null 來作為鍵不存在的標識。因此,, IDictionary<K, V>Dictionary<K, V> 的索引器在指定鍵不存在的情況下將拋出 KeyNotFoundException 異常,。這將導致源代碼級別的不兼容,也就是說,,以下的代碼在存儲值類型的情況下將不可移植,,而必須改寫(例如先使用 ContainsKey 方法判斷指定鍵是否存在,然后再訪問,;或者使用不拋出異常的 TryGetValue 方法):

 

Hashtable map = ...;

if (map[“s1”] == null) { // 如果是范型版本將拋出異常而不是返回null

...

}

 

這一問題反映了設計者在最初設計 Hashtable 類的時候考慮的并不是很周到——使用了魔術值 null,,既可以是指鍵不存在的情況,也可以是鍵存在而值為 null 的情況,,而這一點對范型是不成立的,。另外,從 Design By Contract 的角度講,,當指定鍵值不存在時,,拋出異常是很自然的事情(與是否使用范型無關),就像數(shù)組越界一樣,。估計原設計者主要是從性能角度考慮才使用了 null 而不是異常處理,。

IComparable<T>IComparer<T> Comparer<T>

這幾個接口/類用于比較和排序,。IComparable<T> 相比 IComparable 添加了 Equals 方法,,當然也是為了盡量減少 boxing(對于值類型類說)。IComparer<T> 相對 IComparer 則不僅添加了 Equals 方法,,而且還新增加了 GetHashCode 方法,。咋看一下似乎和比較不太相關,但事實上,,對于字符串來說,,比較和哈希值是息息相關的。在以前的非范型設計中,,需要同時使用 IComparer IHashCodeProvider 兩個接口,,例如 Hashtable 的構造函數(shù):

 

public Hashtable(IHashCodeProvider hcp, IComparer comparer);

 

其中 IHashCodeProvider IComparer 兩個參數(shù)必須匹配(例如都使用 InvariantCultureIgnoreCase),否則結果會不正確。為了讓程序員能夠快速的編寫出正確的代碼,,現(xiàn)在的 IComparer<T> 把比較和生成哈希代碼的功能集成在一起,,例如 Dictionary<K, V> 的構造函數(shù):

 

public Dictionary(IComparer<K, V> comparer);

 

Comparer<K, V> 提供了 IComparer<K, V> 的默認實現(xiàn),微軟最新的設計指南建議使用 Comparer<K, V> 而不是其他方法來比較和排序,。

另外,,.NET 2.0 中新添加了一個字符串比較類——StringComparer,位于 System 命名空間,。StringComparer 不是一個范型類,,不過它實現(xiàn)了 IComparer<string> 接口,對于需要提供大小寫無關的字符串比較很有用,。例如,,下面的代碼創(chuàng)建了一個大小寫無關的字典:

 

Dictionary<string, int> dict = new Dictionary<string, int>(StringComparer.InvariantCultureIgnoreCase);

dict[“Test”] = 10;

int n = dict[“test”];

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,,謹防詐騙,。如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊一鍵舉報,。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多