.NET 4.0中数组的新增功能

  1、两数组是否“相等”?

  在实际开发中,有时我们需要比对两个数组是否拥有一致的元素,例如,以下两个数组由于拥有相同的元素,因此被认为是相等的:

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)使用EqualityComparer静态属性Default获取一个.NET4.0针对泛型类型T所提供的默认“集合对象相等比较器”对象的引用,同样地,它没有将程序集内部的某个具体类型发布出去,而是玩了一点小花样,发布了一个实现了IEqualityComparer接口的公有抽象基类EqualityComparer:

public abstract class EqualityComparer :

IEqualityComparer, IEqualityComparer

{

public static EqualityComparer Default { get; }

//...

}

  可以将.NET基类库设计者的设计思路表述为下图 。

  因此,使用上述两种方式的任意一种,我们可以写出以下代码来直接判断两个整型数组是否拥有完全一致元素:

bool IsEqual1=(arr1 as IStructuralEquatable).Equals(

arr2, StructuralComparisons.StructuralEqualityComparer);

bool IsEqual2=(arr1 as IStructuralEquatable).Equals(

arr2, EqualityComparer.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)通过Comparer.Default属性获取针对特定类型的默认“集合对象大小比较器”对象。

  由此,我们可以写出以下代码来比较两个整型数组谁大谁小:

int result1=(arr1 as IStructuralComparable).CompareTo(

arr2, StructuralComparisons.StructuralComparer);

int result2= (arr1 as IStructuralComparable).CompareTo(

arr2,Comparer.Default)

  如果arr1>arr2,我们得到“1”;arr1,我们得到“-1”;arr1“等于”arr2,我们得到“0”。

  3、小结

  由于.NET 4.0让数组基类Array实现了IStructuralEquatable和IStructuralComparable两个接口,从而使得所有数组都可以直接比较其内容了。

  通常情况下,使用.NET 4.0提供的几个预定义集合对象比较器就足够了,不过,我们也可以通过定义自己的“集合对象相等比较器”(只需定义一个实现IEqualityComparer 接口的类)或“集合对象大小比较器”(只需定义一个实现IComparer接口的类),从而定义自己的数组比较规则。

  对于其元素为自定义引用类型的数组,推荐让此自定义类型实现IComparable接口,并且重写Object.Equals()方法。这么做的目的是让数组中的所有对象都可以相互比较,并且能直接调用数组基类Array所提供的排序、查找、筛选等功能。

  另外,.NET基类库中相关的设计方案也是值得大家学习借鉴的。

  我在本文中详细介绍了.NET基类库如何设计集合对象相等比较器,但没有介绍它是如何设计集合对象大小比较器的,这个进一步深入探索的任务就留给好奇心强的读者,我只想指出一点,.NET 基类库中,集合对象大小比较器与集合对象相等比较器的设计思路是类似的。

时间: 2024-09-20 20:38:51

.NET 4.0中数组的新增功能的相关文章

艾伟_转载:.NET 4.0中数组的新增功能

1.两数组是否"相等"? 在实际开发中,有时我们需要比对两个数组是否拥有一致的元素,例如,以下两个数组由于拥有相同的元素,因此被认为是相等的: int[] arr1 = new int[]{1,2,3,4};int[] arr2 = new int[]{1,2,3,4}; 在.NET早期版本中,要实现上述数组比对功能,必须自己动手编写一个函数,在其内部使用循环语句逐个比较两个数组的对应元素,才知道这两个数组是否相等. 在.NET 4.0中,数组基类Array实现了一个新增的接口IStr

Excel 2010 中条件格式新增功能介绍

Excel 2010 中条件格式新增功能介绍这篇文章的内容如下: 下面介绍Excel 2010中一些新的条件格式功能: 交叉表引用 健壮的错误处理 性能增强 交叉表引用 在Excel 2010中,可以创建引用工作簿中不同工作表的条件格式.这意味着,在使用条件格式时,不再需要复制或链接数据到同一工作表. 例如,看看某连锁书店每月销售数据,该书店采用如下方式组织销售数据: 每个位置有自已的工作表 最后一个工作表包含全公司累计销售数据,使用每个部门的平均值. 下面我们应用条件格式,以便能够容易判断是否

IIS6.0下ASP的新增功能

iis ASP 的新增功能除了内部性能增强和优化外,该版本的 Active Server Pages(ASP) 还具有如下新功能: 更好的国际化和 UTF-8 支持 改进的 POST 支持 ASP 挂起检测 常用文件的缓存 UNC 增强 ASP 中的 COM+ 服务 单元模型选择 并排集合 COM+ 分区 跟踪程序 事务 ASP 的新配置数据库属性 更好的国际化和 UTF-8 支持UTF-8 支持已经被扩展到所有 ASP 内置对象的属性和方法中.上一版本的 ASP 仅在响应和写入方面支持 UTF

ASP.NET 2.0 中改进的缓存功能

asp.net|缓存 Stephen Walther      Microsoft Corporation      适用于:      Microsoft ASP.NET 2.0      Microsoft ASP.NET Framework      Microsoft SQL Server      Microsoft Visual Studio .NET      摘要:本文中,Stephen Walther 将重点介绍 ASP.NET 2.0 中新增的缓存功能,以及如何使用这些新功能

搜狗输入迎来安卓3.0预览版 新增功能丰富

作为国内几大搜索引擎之一,搜狗输入法一直用户的喜爱,而近日搜狗超级手机输入法迎来了安卓3.0预览版,新增了多媒体输入,你可以在短信中直接发送语音.图片,该版本还支持云输入.二维码随拍随换肤等,丰富的新增功能将给用户带来新的体会和惊喜. 搜狗超级手机输入法安卓3.0预览版更新日志: 新增功能 1.1 多媒体输入:随时随地说一段话.拍一张图,在短信里就能将你的喜怒哀乐传递给朋友: 1.2 云输入:搜狗云端计算能力提供更精准的输入结果: 1.3 二维码识别:拍皮肤.拍名片.拍条码,只要你拍,搜狗就能将

ASP.NET 2.0 中的异步页功能应用

asp.net|异步 下载本文源代码:WickedCode0510.exe ASP.NET 2.0 提供了大量新功能,其中包括声明性数据绑定和母版页,成员和角色管理服务等.但我认为最棒的功能是异步页,接下来让我告诉您其中的原因. 当 ASP.NET 接收针对页的请求时,它从线程池中提取一个线程并将请求分配给该线程.一个普通的(或同步的)页在该请求期间保留线程,从而防止该线程用于处理其他请求.如果一个同步请求成为 I/O 绑定(例如,如果它调用一个远程 Web 服务或查询一个远程数据库,并等待调用

ASP.NET 2.0中的异步页功能应用

ASP.NET 2.0 提供了大量新功能,其中包括声明性数据绑定和母版页,成员 和角色管理服务等.但我认为最棒的功能是异步页,接下来让我告诉您其中的原 因. 当 ASP.NET 接收针对页的请求时,它从线程池中提取一个线程并将请求分配 给该线程.一个普通的(或同步的)页在该请求期间保留线程,从而防止该线程 用于处理其他请求.如果一个同步请求成为 I/O 绑定(例如,如果它调用一个 远程 Web 服务或查询一个远程数据库,并等待调用返回),那么分配给该请求 的线程在调用返回之前处于挂起状态.这影响

ASP.NET 2.0 中收集的小功能点

asp.net 1.asp.net 2.0中的MaxPageStateFieldLength 属性 在asp.net 2.0中,可以强制对viewstate进行分段传输了,使用的是Page.MaxPageStateFieldLength 属性,可以设置viewstate中,每个页面状态字段的最大字节数.格式如下,要在WEB.CONFIG文件里设置的:    <pages maxPageStateFieldLength="5" />    其中,将设置把viewstate为不

ASP.NET 2.0 中收集的小功能点(转)_实用技巧

1.asp.net 2.0中的MaxPageStateFieldLength 属性 在asp.net 2.0中,可以强制对viewstate进行分段传输了,使用的是Page.MaxPageStateFieldLength 属性,可以设置viewstate中,每个页面状态字段的最大字节数.格式如下,要在WEB.CONFIG文件里设置的:<pages maxPageStateFieldLength="5" />其中,将设置把viewstate为不超过5字节,如果实际的views