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