詳解.NET 4.0中的類型和元組
原創【51CTO獨家特稿】在.NET 4.0框架中元組是一組屬性,為了你提供了一種更容易將數據塊拼湊在一起的方法,而不必編寫自己的類。有不同大小的元組,從一個單一類型屬性的元組Tuple(Of T1)到有八個或更多類型的元組。例如,雙重和三重元組的類型定義縮寫看起來象下面這樣。51CTO曾報道過《.NET 4.0中任務與線程關系談》
- Class Tuple(Of T1, T2)
- ReadOnly Property Item1 As T1
- ReadOnly Property Item2 As T2
- ...
- End Class
- Class Tuple(Of T1, T2, T3)
- ReadOnly Property Item1 As T1
- ReadOnly Property Item2 As T2
- ReadOnly Property Item3 As T3
- ...
- End color=#006699>Class
三重元組(Tuple(Of T1, T2, T3))允許你分組三個不同的任意類型的數據塊:你可以存儲三個字符串,或者一個字符串、一個整數和一個日期等組合。元組的名稱據說來自序列:如單,雙,三,四,五,六,七,八….n元組。在編程語言,如Python和F#中,你會發現也有元組,現在在.NET 4.0的mscorlib庫中也有元組了,在未來你可能會在Visual Basic(VB)和C#代碼中發現它們的蹤跡。
因為元組的數據屬性是只讀的,.NET中的元組被認為是不可修改的,如果你要修改一個值,必須創建另一個元組。要創建一個新的元組,你可以指定泛型參數類型,然后將數據值傳遞給構造函數。
- Dim person As New Tuple
- (Of String, String, Date) ("John", "Citizen", #1/1/1980#)
一個簡單的語法是在元組類上使用Create工廠方法,并利用VB的類型推斷:
- Dim person = Tuple.Create("John", "Citizen",#1/1/1980#)
調用Tuple.Create依賴于類型推斷,如果沒有類型推斷,你必須編寫自己的方法進行調用,并需要明確泛型參數,這樣就完成否決了Share工廠方法的優勢。
- Dim person As Tuple(Of String, String, Date)
- = tuple.Create("John", "Citizen", #1/1/1980#)
注意,即使類型推斷選項被關閉了 ,調用Create方法時仍然不需要指定泛型參數。
使用元組的一個問題是你的代碼變得不好描述,因為元組沒有描述屬性名稱,如person.Item1和person.Item2,在你的項目中快速添加一個簡單類定義會更有意義,在Visual Studio 2010中創建一個簡單的類比以前容易多了。
以我們的Person類和FirstName,LastName和DateOfBirth字段為例,在VB 10中,你可以使用自動屬性減少代碼量。
- Class Person
- Property FirstName As String
- Property LastName As String
- Property DateOfBirth As Date
- End Class
你不用再為一個屬性聲明后備字段,如getter和setter塊,只需要屬性名和它的類型即可。
VB和C#中的自動屬性有很大的不同,在VB和C#中,編譯器生成后備字段,以及與屬性相關的get和set代碼塊,C#為后備字段產生一個名字,但在你的代碼中卻不能使用它,而在VB卻允許你訪問這些后備字段。以FirstName屬性作為例子,在C#中后備字段名字可能是 在VB語言規范中明確指出可以通過名字可以訪問后備字段,因此你可以放心使用,它是安全的,一個很好的例子是當添加一個參數到你類的構造函數中時,在VB中這是一個非常簡單的任務。 要在C#中實現同樣的功能,你必須將所有自動屬性修改為標準屬性,并自行聲明后備字段,并在后備字段上添加get和set代碼塊。
注意在VB中的代碼實際上是不需要逗號后面的連接符“_”,我這么做只是為了使代碼更易讀。
Visual Studio IDE也可以幫你生成類,它們的屬性和構造函數,如果你的代碼引用了一個不存在的類型,會有錯誤更正功能幫助你生成類。
錯誤更正功能為你生成了Person類,包括一個參數的構造函數。生成的代碼如下:
如果你現在退回去使用With {. }語法修改你的變量聲明初始化屬性,更正向導會建議你添加屬性,雖然你可以使用通用代碼功能快速創建一個類,但仍然需要自己編寫屬性,要么使用代碼片段要么使用自動屬性語法。通用代碼功能的幾大亮點是當你向類中增加一個方法時,你可能不想停下來,然后自己添加一個方法或屬性,而是希望將注意力放在當前的代碼流中,但在添加屬性時應謹慎使用,因為添加屬性時有很多其它代碼需要修改。
#T# 在聲明只讀屬性時,無論是通用代碼功能還是自動屬性都可以幫到你。為了創建一個不可修改的類,你仍然需要自己動手在Visual Studio 2010中寫幾行代碼。
為了使你的類和元組類有相同的功能,你也需要基于你的后備字段添加同等的ToString和GetHashCode代碼。ToString方法非常適合調式和測試,GetHashCode方法重點在排序、比較和字典式存儲上,Equals方法也應該重寫,此外,你需要實現IComparable和它的CompareTo函數以允許排序。
元組類代碼已經到位,它們甚至實現了兩個新的接口:IStructuralComparable 和 IStructuralEquatable。這些接口提供了CompareTo函數和一個額外的IComparer參數,以及Equals和參數為IEqualityComparer 的GetHashCode函數,它允許自定義排序。
自己動手編寫所有的代碼工作量非常大,至少你應該考慮將GetHashCode添加到你的類中,如果你使用代碼生成功能,它會向你的類添加一個屬性,你可以繼續編你的碼,但可以忘掉你要打開的文件,它可以修復你的GetHashCode和其它方法。
元組的優點
當你完全了解了元組后,你就會知道它的好處,盡管它們有不倫不類的Item1,Item2,Item3等屬性。元組類是固定的,你不能修改它。你也不必處理跨機器邊界和分布式類型信息的問題,因為在.NET 4.0中,元組在mscorlib庫中,甚至還有一些不錯的嘗試,如TargetedPatchingOptOut屬性修飾,因此允許屬性是跨本地圖形生成器的圖像。
毫無疑問,使用元組可以減少代碼量,當你在VB10中將元組和lambda表達式結合使用時,可以大大減少代碼量。下面是我最近一篇文章中使用到的代碼,是在VB10中完成的,但如果在VB9中代碼量要多出一倍。使用元組和lambda表達式完全去除了我之前需要的PropertyChangedEventContext類。元組為事件處理程序和同步上下文提供了基本的數據存儲,剩下需要做的事情是能夠將事件處理程序傳遞給同步上下文的Post方法。
代碼段1:在Visual Studio 2010中使用元組和lambda方法簡化你的代碼
雖然元組看起來可能比較簡單和優點不倫不類的樣子,但它提供了強大的類型和重要的比較功能,元組在跨方法、類甚至機器邊界時非常有用,合理地使用它們將會節省你大量的編碼時間。
原文出處:http://visualstudiomagazine.com/Articles/2009/12/01/Types-and-Tuples-in-NET-4.aspx
原文名:Types and Tuples in .NET 4
作者:Bill McCarthy