詳解.NET 4.0數(shù)組的相關(guān)新增功能
在.NET 4.0中我們將看到數(shù)組方面有很大的改進,本文將給大家討論的是.NET 4.0數(shù)組的新增功能,希望對大家用好.NET 4.0數(shù)組有所幫助。
1 兩數(shù)組是否“相等”?
在實際開發(fā)中,有時我們需要比對兩個數(shù)組是否擁有一致的元素,例如,以下兩個數(shù)組由于擁有相同的元素,因此被認為是相等的:
- int[] arr1 = new int[]
- {
- 1,2,3,4
- };
- int[] arr2 = new int[]
- {
- 1,2,3,4
- };
在.NET早期版本中,要實現(xiàn)上述數(shù)組比對功能,必須自己動手編寫一個函數(shù),在其內(nèi)部使用循環(huán)語句逐個比較兩個數(shù)組的對應(yīng)元素,才知道這兩個數(shù)組是否相等。
在.NET 4.0中,數(shù)組基類Array實現(xiàn)了一個新增的接口IStructuralEquatable,從而使得所有數(shù)組都可直接比對其所擁有的元素是否相等。
IStructuralEquatable接口的定義如下,其中最重要的成員就是它所定義的Equals()方法。
- public interface IStructuralEquatable
- {
- bool Equals(object other, IEqualityComparer comparer);
- int GetHashCode(IEqualityComparer comparer);
- }
上述聲明中還涉及另一個接口IEqualityComparer,它的聲明如下:
- public interface IEqualityComparer
- {
- bool Equals(object x, object y);
- int GetHashCode(object obj);
- }
實現(xiàn)了IEqualityComparer接口的對象被稱為“集合對象相等比較器”。
.NET 4.0基類庫中提供了好幾個直接可用的“集合對象相等比較器”,有兩種方式獲取這些預(yù)定義的“集合對象相等比較器”:
(1)使用StructuralComparisons類的靜態(tài)屬性StructuralEqualityComparer獲取一個StructuralEqualityComparer類型實例的引用。
延伸閱讀:
“程序集接口最小化”設(shè)計原則
StructuralComparisons和StructuralEqualityComparer這兩個類型均屬于System.Collections命名空間,位于.NET的核心程序集mscorlib.dll內(nèi),前者是public的,而后者是internal的。
默認情況下,聲明為internal的類型只能在本程序集內(nèi)使用,其它程序集無法“看到”它。
因此,StructuralComparisons類在定義其靜態(tài)屬性StructuralEqualityComparer時,沒有直接向外界暴露StructuralEqualityComparer類型,而是將其轉(zhuǎn)換為公有的IEqualityComparer接口:
- public static class StructuralComparisons
- {
- public static IEqualityComparer StructuralEqualityComparer { get; }
- //……
- }
這種設(shè)計方法貫徹了.NET組件化開發(fā)中的“程序集接口最小化”原則。該原則說:設(shè)計一個程序集時應(yīng)該盡可能地減少聲明為public的類型。
.NET設(shè)計者在設(shè)計public類型StructuralComparisons時,沒有讓其靜態(tài)屬性直接將一個StructuralEqualityComparer對象的引用返回給外界,而將其轉(zhuǎn)換為一個外界“知道”的公有接口IEqualityComparer,從而將StructuralEqualityComparer類型的定義完全封裝在程序集內(nèi)部,外界甚至不知道有這么一個類型的存在。
這種設(shè)計方式的好處是:
我們可以在程序集內(nèi)部設(shè)計任意多個實現(xiàn)了IEqualityComparer接口的類型,由于這些類型對于外界而言是“透明”的,因此,程序集內(nèi)部的修改對外界程序集使用者可能帶來的影響就很小了。
這種設(shè)計方法值得注意。
(2)使用EqualityComparer<T>靜態(tài)屬性Default獲取一個.NET4.0針對泛型類型T所提供的默認“集合對象相等比較器”對象的引用,同樣地,它沒有將程序集內(nèi)部的某個具體類型發(fā)布出去,而是玩了一點小花樣,發(fā)布了一個實現(xiàn)了IEqualityComparer接口的公有抽象基類EqualityComparer<T>:
- public abstract class EqualityComparer<T> :
- IEqualityComparer, IEqualityComparer<T>
- {
- public static EqualityComparer<T> Default { get; }
- //...
- }
可以將.NET基類庫設(shè)計者的設(shè)計思路表述為下圖 。
因此,使用上述兩種方式的任意一種,我們可以寫出以下代碼來直接判斷兩個整型數(shù)組是否擁有完全一致元素:
- bool IsEqual1=(arr1 as IStructuralEquatable).Equals(
- arr2, StructuralComparisons.StructuralEqualityComparer);
- bool IsEqual2=(arr1 as IStructuralEquatable).Equals(
- arr2, EqualityComparer<int>.Default)
當(dāng)比對兩個數(shù)組時,如果兩個數(shù)組的長度不一樣,數(shù)組基類Array所實現(xiàn)的IStructuralEquatable.Equals()方法將返回false,否則,它逐個比較兩個數(shù)組的對應(yīng)元素,找到一個不同的,返回false,如果一直比較完所有元素,都沒有發(fā)現(xiàn)有不同的,則Equals()方法返回true。
2兩個數(shù)組“誰大誰小”?
如果兩個數(shù)組的長度一樣,我們還可以定義這兩個數(shù)組“誰大誰小”:
- int[] arr1 = new int[]
- {
- 1,2,3,4
- };
- int[] arr2 = new int[]
- {
- 1,2,3,5
- };
上述兩個數(shù)組中,由于arr1與arr2前幾個元素都相等,但第4個元素arr2大于arr1,所以,我們認為:arr2“大于”arr1
為了比較兩個集合的大小,.NET 4.0引入了一個新的接口IStructuralComparable,并且讓數(shù)組基類Array也實現(xiàn)了此接口,這意味著在.NET 4.0中,兩個數(shù)組對象是可以比較“大小”的。
- public interface IStructuralComparable
- {
- int CompareTo(object other, IComparer comparer);
- }
注意上面的接口聲明中用到了一個實現(xiàn)IComparer接口的“集合對象大小比較器”對象。.NET基類庫同樣提供了幾個默認的“集合對象大小比較器”可供直接使用,也有兩種方式獲取這些默認的“集合對象大小比較器”實例:
(1)通過我們前面用過的StructuralComparisons類的另一個靜態(tài)屬性StructuralComparer獲取,它在內(nèi)部使用System.Collections.Comparer類的Default靜態(tài)屬性所引用的包容了本地文化信息(CultureInfo)的Comparer對象來完成比較大小的工作,此對象是CLR在裝入程序集時創(chuàng)建的。
(2)通過Comparer<T>.Default屬性獲取針對特定類型的默認“集合對象大小比較器”對象。
由此,我們可以寫出以下代碼來比較兩個整型數(shù)組誰大誰?。?/P>
- int result1=(arr1 as IStructuralComparable).CompareTo(
- arr2, StructuralComparisons.StructuralComparer);
- int result2= (arr1 as IStructuralComparable).CompareTo(
- arr2,Comparer<int>.Default)
如果arr1>arr2,我們得到“1”;arr1<arr2,我們得到“-1”;arr1“等于”arr2,我們得到“0”。
3 小結(jié)
由于.NET 4.0數(shù)組基類Array實現(xiàn)了IStructuralEquatable和IStructuralComparable兩個接口,從而使得所有數(shù)組都可以直接比較其內(nèi)容了。
#T#
通常情況下,使用.NET 4.0提供的幾個預(yù)定義集合對象比較器就足夠了,不過,我們也可以通過定義自己的“集合對象相等比較器”(只需定義一個實現(xiàn)IEqualityComparer 接口的類)或“集合對象大小比較器”(只需定義一個實現(xiàn)IComparer接口的類),從而定義自己的數(shù)組比較規(guī)則。
對于其元素為自定義引用類型的數(shù)組,推薦讓此自定義類型實現(xiàn)IComparable接口,并且重寫Object.Equals()方法。這么做的目的是讓數(shù)組中的所有對象都可以相互比較,并且能直接調(diào)用數(shù)組基類Array所提供的排序、查找、篩選等功能。
另外,.NET基類庫中相關(guān)的設(shè)計方案也是值得大家學(xué)習(xí)借鑒的。
我在本文中詳細介紹了.NET基類庫如何設(shè)計集合對象相等比較器,但沒有介紹它是如何設(shè)計集合對象大小比較器的,這個進一步深入探索的任務(wù)就留給好奇心強的讀者,我只想指出一點,.NET 基類庫中,集合對象大小比較器與集合對象相等比較器的設(shè)計思路是類似的。
原文標題:.NET 4.0中數(shù)組的新增功能
鏈接:http://www.cnblogs.com/bitfan/archive/2009/12/27/1633625.html