《面向对象的艺术》之.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实现了一个新增的接口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”。

 

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值