`
wsql
  • 浏览: 11778542 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
文章分类
社区版块
存档分类
最新评论

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

public abstract class EqualityComparer<T> :

IEqualityComparer, IEqualityComparer<T>

{

public static EqualityComparer<T> Default { get; }

//...

}

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

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

bool IsEqual1=(arr1 as IStructuralEquatable).Equals(

arr2, StructuralComparisons.StructuralEqualityComparer);

bool IsEqual2=(arr1 as IStructuralEquatable).Equals(

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

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

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 小结
由于.NET 4.0让数组基类Array实现了IStructuralEquatable和IStructuralComparable两个接口,从而使得所有数组都可以直接比较其内容了。

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

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

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

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


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/bitfan/archive/2009/12/27/5087850.aspx

分享到:
评论

相关推荐

    cSharpCollectionFundamentals:Pluralsight C#集合基础课程的源代码-Source code collection

    C#收集基础知识 该存储库包含示例代码。... 理想情况下,它应与.net Framework 4.0及更高版本一起使用,但尚未对其进行测试。 示例包含以下内容: 数组 馆藏 链接列表,堆栈和队列 辞典 套 枚举器 多维数组

    C#4.0权威指南.pd

    内容全面,不仅重点讲解了C# 4.0的所有新特性,而且对C#的所有知识点的原理、用法和要点都进行了全面的讲解和深度的分析,广度和深度完美结合。《C# 4.0权威指南》注重实践,包含大量有价值的示例代码,可操作性极强...

    C# 4.0权威指南-姜晓东

    内容新颖,基于新的C# 4.0、net framework 4和visual studio 2010;写作方式有创新,用图解的方式对C#进行了完美的演绎;内容全面,不仅重点讲解了C# 4.0的所有新特性,而且对C#的所有[0知0]识点的原理、用[0法0]和...

    C#语言规范4.0.PDF_带书签功能

    于 .NET Framework 的 C# 编译器就是根据这两个标准实现的。 C# 是面向对象的语言,然而 C# 进一步提供了对面向组件 面向组件 面向组件 面向组件 (component-oriented) 编程的支持。现代软件 设计日益依赖于自包含...

    C# 4.0语言规范

    Microsoft 用于 .NET Framework 的 C# 编译器就是根据这两个标准实现的。 C# 是面向对象的语言,然而 C# 进一步提供了对面向组件 (component-oriented) 编程的支持。现代软件设计日益依赖于自包含和自描述功能包...

    Visual C# 2010程序设计教程(教程PPT+源代码)

    1.1.1 .NET Framework 4.0概述 1.1.2 理解命名空间 1.2 Visual Studio 2010简介 1.2.1 Visual Studio 2010开发环境概览 1.2.2 菜单栏 1.2.3 工具栏 1.2.4 “属性”及“解决方案资源管理器”面板 1.2.5 其他面板 ...

    CLR via C# 中文版 第三版(高清_全_part1.rar)

    2010年2月,Jeffrey Richter又推出了针对Visual Studio 2010、.NET 4.0、C# 4.0的集大成之作《CLR via C#》第三版。    本书分为五个部分:    第一部分,CLR基础(CLR Basics),介绍CLR的执行模型,程序集...

    CLR via C# 中文版 第三版(高清_全_part2.rar)

    2010年2月,Jeffrey Richter又推出了针对Visual Studio 2010、.NET 4.0、C# 4.0的集大成之作《CLR via C#》第三版。    本书分为五个部分:    第一部分,CLR基础(CLR Basics),介绍CLR的执行模型,程序集...

    《C#经典编程220例》.(明日科技).【带书签】-共3部分

    自制书签。因上传大小限制,分三卷压缩,分别是:《C#经典编程220例》.(明日科技).【带书签】.zip、《C#经典编程220例》.(明日科技).【带书签】.z01、《C#经典编程220例》....实例220 打包.net framework 4.0框架 420

    明日科技C#开发入门及项目实战

    内附1-19章的实战程序。 目录 第1章 c#语言及其开发环境 实例001 根据需要创建所需解决方案 实例002 统一窗体中控件的字体设置 实例003 设置程序代码行号 实例004 通过“格式”...实例220 打包.net framework 4.0框架

    Visual C#2010 从入门到精通(Visual.C#.2010.Step.By.Step).完整去密码锁定版 I部分

    visual c# 2010新增了大量可圈可点的丰富特性,本书围绕着基础知识和这些新特性全面介绍了如何利用visual studio 2010和.net framework 4.0编写应用程序。书中沿袭深受读者欢迎的step by step风格,通过丰富的练习...

    CLR.via.C#.(中文第3版)(自制详细书签)

    《CLR via C#(第3版) 》针对.NET Framework 4.0和多核编程进行了全面更新和修订,是帮助读者深入探索和掌握公共语言运行时、C#和.NET开发的重要参考,同时也是帮助开发人员构建任何一种应用程序(如Microsoft ...

    CLR.via.C#.(中文第3版)(自制详细书签)Part1

    《CLR via C#(第3版) 》针对.NET Framework 4.0和多核编程进行了全面更新和修订,是帮助读者深入探索和掌握公共语言运行时、C#和.NET开发的重要参考,同时也是帮助开发人员构建任何一种应用程序(如Microsoft ...

    CLR.via.C#.(中文第3版)(自制详细书签)Part3

    《CLR via C#(第3版) 》针对.NET Framework 4.0和多核编程进行了全面更新和修订,是帮助读者深入探索和掌握公共语言运行时、C#和.NET开发的重要参考,同时也是帮助开发人员构建任何一种应用程序(如Microsoft ...

    CLR.via.C#.(中文第3版)(自制详细书签)Part2

    《CLR via C#(第3版) 》针对.NET Framework 4.0和多核编程进行了全面更新和修订,是帮助读者深入探索和掌握公共语言运行时、C#和.NET开发的重要参考,同时也是帮助开发人员构建任何一种应用程序(如Microsoft ...

Global site tag (gtag.js) - Google Analytics