代码改变世界

比较IComparer,IComparable,IEqualityComparer,IEquatable之深入接口

2011-08-19 16:15  symphony2010  阅读(748)  评论(0编辑  收藏  举报

学到接口这块,有点迷惑比较一下有助于理清思路。(写在北大青鸟潘家园校区)

很多的类型都继承自这些方法,我相信理解这些很重要

大家其实可以直接去查MSDN,列在这里只是为了有一个清晰的比较

定义

IComparer Exposes a method that compares two objects.
对外暴露比较两个对象的方法
IComparable Defines a generalized type-specific comparison method that a value type or class implements to order or sort its instances.
定义一个值类型或者引用的泛型指定类型的比较方法,来执行对它的实例进行排序或者分类
IEqualityComparer Defines methods to support the comparison of objects for equality.
定义一个方法支持对象是否相等的比较

IEquatable<T>(竟然没有非泛型类,另作研究)

Defines a generalized method that a value type or class implements to create a type-specific method for determining equality of instances.
定义一个值类型或者引用类型的泛型方法来创建一个特定类型的方法来判断实例是否相等

方法

IComparer

Public method

int Compare(
	Object x,
	Object y
)

Compares two objects and returns a value indicating whether one is less than, equal to, or greater than the other.

IComparable
int CompareTo(
	Object obj
)
Compares the current instance with another object of the same type and returns an integer that indicates whether the current instance precedes, follows, or occurs in the same position in the sort order as the other object.
IEqualityComparer bool Equals(
Object x,
Object y
)
Determines whether the specified objects are equal.
 
int GetHashCode(
	Object obj
)
Returns a hash code for the specified object.

IEquatable<T>

bool Equals(
T other
)
Indicates whether the current object is equal to another object of the same type.

 

自己的理解

IComparer的方法中,Compare 有这样一句:

This interface is used in conjunction with the Array.Sort and Array.BinarySearch methods. It provides a way to customize the sort order of a collection. See the Compare method for notes on parameters and return value.

微软提供的例子里怎么理解里面结合了Array.BinarySearch:

using System;
using System.Collections;

public class SamplesArrayList  {

   public class myReverserClass : IComparer  {

      // Calls CaseInsensitiveComparer.Compare with the parameters reversed.
      int IComparer.Compare( Object x, Object y )  {
          return( (new CaseInsensitiveComparer()).Compare( y, x ) );//这里结合了Array.BinarySearch?反汇编看看究竟(在下面演示)
      }

   }

   public static void Main()  {

      // Creates and initializes a new ArrayList.
      ArrayList myAL = new ArrayList();
      myAL.Add( "The" );
      myAL.Add( "quick" );
      myAL.Add( "brown" );
      myAL.Add( "fox" );
      myAL.Add( "jumps" );
      myAL.Add( "over" );
      myAL.Add( "the" );
      myAL.Add( "lazy" );
      myAL.Add( "dog" );

      // Displays the values of the ArrayList.
      Console.WriteLine( "The ArrayList initially contains the following values:" );
      PrintIndexAndValues( myAL );

      // Sorts the values of the ArrayList using the default comparer.
      myAL.Sort();
      Console.WriteLine( "After sorting with the default comparer:" );
      PrintIndexAndValues( myAL );

      // Sorts the values of the ArrayList using the reverse case-insensitive comparer.
      IComparer myComparer = new myReverserClass();
      myAL.Sort( myComparer );//还是这里结合了Array.BinarySearch?
      Console.WriteLine( "After sorting with the reverse case-insensitive comparer:" );
      PrintIndexAndValues( myAL );

   }

   public static void PrintIndexAndValues( IEnumerable myList )  {
      int i = 0;
      foreach ( Object obj in myList )
         Console.WriteLine( "\t[{0}]:\t{1}", i++, obj );
      Console.WriteLine();
   }

}
 
 

需要加载符号表才能进入mscrolib.dll调试

在此处设置断点:

image

image

然后进入到下面这个函数:

public virtual int Compare(string string1, string string2, CompareOptions options)
    {
      if (options == CompareOptions.OrdinalIgnoreCase)
      {
        return string.Compare(string1, string2, StringComparison.OrdinalIgnoreCase);
      }
      if ((options & CompareOptions.Ordinal) != CompareOptions.None)
      {
        if (options != CompareOptions.Ordinal)
        {
          throw new ArgumentException(Environment.GetResourceString("Argument_CompareOptionOrdinal"), "options");
        }
        return string.CompareOrdinal(string1, string2);
      }
      if ((options & ~(CompareOptions.StringSort | CompareOptions.IgnoreWidth | CompareOptions.IgnoreKanaType | CompareOptions.IgnoreSymbols | CompareOptions.IgnoreNonSpace | CompareOptions.IgnoreCase)) != CompareOptions.None)
      {
        throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFlag"), "options");
      }
      if (string1 == null)
      {
        if (string2 == null)
        {
          return 0;
        }
        return -1;
      }
      if (string2 == null)
      {
        return 1;
      }
      return InternalCompareString(this.m_dataHandle, this.m_sortName, string1, 0, string1.Length, string2, 0, string2.Length, GetNativeCompareFlags(options));
    }

还没找到BinarySearch的影子,看看是不是myAL.Sort( myComparer );里面有什么名堂:

image

 

image

 

 image

image

最后进入最为关键的代码,在接口里面实现的代码在此时影响着排序的结果,即使在接口里Console.Write("Hello,World");也会在这里执行输出

image

今天虽然没找到BinarySearch的影子,也算对接口的内部运行有了一些了解。

以后接着聊这些接口的不同。