.NET 4.0中数组的新增功能

📅 2026/7/6 1:59:58
.NET 4.0中数组的新增功能
两数组是否“相等”在实际开发中有时我们需要比对两个数组是否拥有一致的元素例如以下两个数组由于拥有相同的元素因此被认为是相等的int[] arr1 new int[]{1,2,3,4};int[] arr2 new int[]{1,2,3,4};在.NET早期版本中要实现上述数组比对功能必须自己动手编写一个函数在其内部使用循环语句逐个比较两个数组的对应元素才知道这两个数组是否相等。在.NET 4.0中数组基类Array实现了一个新增的接口IStructuralEquatable从而使得所有数组都可直接比对其所拥有的元素是否相等。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);}实现了IEqualityComparer接口的对象被称为“集合对象相等比较器”。.NET 4.0基类库中提供了好几个直接可用的“集合对象相等比较器”有两种方式获取这些预定义的“集合对象相等比较器”1使用StructuralComparisons类的静态属性StructuralEqualityComparer获取一个StructuralEqualityComparer类型实例的引用。延伸阅读“程序集接口最小化”设计原则StructuralComparisons和StructuralEqualityComparer这两个类型均属于System.Collections命名空间位于.NET的核心程序集mscorlib.dll内前者是public的而后者是internal的。默认情况下声明为internal的类型只能在本程序集内使用其它程序集无法“看到”它。因此StructuralComparisons类在定义其静态属性StructuralEqualityComparer时没有直接向外界暴露StructuralEqualityComparer类型而是将其转换为公有的IEqualityComparer接口public static class StructuralComparisons{public static IEqualityComparer StructuralEqualityComparer { get; }//……}这种设计方法贯彻了.NET组件化开发中的“程序集接口最小化”原则。该原则说设计一个程序集时应该尽可能地减少声明为public的类型。.NET设计者在设计public类型StructuralComparisons时没有让其静态属性直接将一个StructuralEqualityComparer对象的引用返回给外界而将其转换为一个外界“知道”的公有接口IEqualityComparer从而将StructuralEqualityComparer类型的定义完全封装在程序集内部外界甚至不知道有这么一个类型的存在。这种设计方式的好处是我们可以在程序集内部设计任意多个实现了IEqualityComparer接口的类型由于这些类型对于外界而言是“透明”的因此程序集内部的修改对外界程序集使用者可能带来的影响就很小了。这种设计方法值得注意。2使用EqualityComparerT静态属性Default获取一个.NET4.0针对泛型类型T所提供的默认“集合对象相等比较器”对象的引用同样地它没有将程序集内部的某个具体类型发布出去而是玩了一点小花样发布了一个实现了IEqualityComparer接口的公有抽象基类EqualityComparerTpublicabstractclass EqualityComparerT :IEqualityComparer, IEqualityComparerT{public static EqualityComparerTDefault{ get; }//...}可以将.NET基类库设计者的设计思路表述为下图 。因此使用上述两种方式的任意一种我们可以写出以下代码来直接判断两个整型数组是否拥有完全一致元素bool IsEqual1(arr1 as IStructuralEquatable).Equals(arr2, StructuralComparisons.StructuralEqualityComparer);bool IsEqual2(arr1 as IStructuralEquatable).Equals(arr2, EqualityComparerint.Default)当比对两个数组时如果两个数组的长度不一样数组基类Array所实现的IStructuralEquatable.Equals()方法将返回false否则它逐个比较两个数组的对应元素找到一个不同的返回false如果一直比较完所有元素都没有发现有不同的则Equals()方法返回true。2两个数组“谁大谁小”如果两个数组的长度一样我们还可以定义这两个数组“谁大谁小”int[] arr1 new int[]{1,2,3,4};int[] arr2 new int[]{1,2,3,5};上述两个数组中由于arr1与arr2前几个元素都相等但第4个元素arr2大于arr1所以我们认为arr2“大于”arr1为了比较两个集合的大小.NET 4.0引入了一个新的接口IStructuralComparable并且让数组基类Array也实现了此接口这意味着在.NET 4.0中两个数组对象是可以比较“大小”的。public interface IStructuralComparable{int CompareTo(object other, IComparer comparer);}注意上面的接口声明中用到了一个实现IComparer接口的“集合对象大小比较器”对象。.NET基类库同样提供了几个默认的“集合对象大小比较器”可供直接使用也有两种方式获取这些默认的“集合对象大小比较器”实例1通过我们前面用过的StructuralComparisons类的另一个静态属性StructuralComparer获取它在内部使用System.Collections.Comparer类的Default静态属性所引用的包容了本地文化信息CultureInfo的Comparer对象来完成比较大小的工作此对象是CLR在装入程序集时创建的。2通过ComparerT.Default属性获取针对特定类型的默认“集合对象大小比较器”对象。由此我们可以写出以下代码来比较两个整型数组谁大谁小int result1(arr1 as IStructuralComparable).CompareTo(arr2, StructuralComparisons.StructuralComparer);int result2 (arr1 as IStructuralComparable).CompareTo(arr2,Comparerint.Default)如果arr1arr2我们得到“1”arr1arr2我们得到“-1”arr1“等于”arr2我们得到“0”。3 小结