zoukankan      html  css  js  c++  java
  • 小谈IEqualityComparer<T>接口

         今天,想使用自定义的类型作为Dictionary<TKey, TValue> 的键类型,不可避免的要使用到这个接口。如果另外定义一个实现类,使用者必须首先知道有这个类存在,这样调用方才会得到正确的结果。自然想到的办法就是这个自定义类型主动实现IEqualityComparer<T>接口,但是Dictionary<TKey, TValue> 类型并不会去检查这个键对象有没有实现IEqualityComparer<T>接口。

         如果构造Dictionary<TKey, TValue> 泛型集合的实例对象时候,没有提供一个实现了IEqualityComparer<T>接口的实例对象,Dictionary<TKey, TValue>默认使用EqualityComparer<T> 泛型类的 Default属性。看看IEqualityComparer<T>接口MSDN的说明:使用此接口,可以实现集合的自定义相等比较。也就是说,对于类型 T,您可以创建自己的相等定义,并指定该定义可与接受 IEqualityComparer<T>泛型接口的集合类型一起使用。在 .NET Framework 中,Dictionary<TKey, TValue> 泛型集合类型的构造函数接受此接口。继续看EqualityComparer<T> 泛型类Default属性的MSDN的说明:Default 属性检查类型 T 是否实现此 System.IEquatable<T> 泛型接口,如果实现,该属性将返回一个使用该实现的 EqualityComparer<T>。否则,它返回一个使用 T 提供的 Object.Equals 和 Object.GetHashCode 的重写的 EqualityComparer<T>。

         看到上面的说明,我天真的以为实现了System.IEquatable<T> 泛型接口就可以在Dictionary<TKey, TValue> 泛型集合的键中使用自己定义的类了。结果发现无论如何都不能使程序按照设想中的运行。最后发现MSDN中关于System.IEquatable<T>的实现者说明:如果实现 IEquatable<T>,还应重写 Object.Equals(Object) 和 GetHashCode 的基类实现,以便其行为与 IEquatable<T>.Equals 方法的行为一致。尝试着重写了这两个方法,一切都OK了。后来查看了.Net Framework源代码才明白了,实际上,对于EqualityComparer<T> 泛型类来说前面这个重写是必须的,因为前面说的“Default 属性检查类型 T 是否实现此 System.IEquatable<T> 泛型接口,如果实现,该属性将返回一个使用该实现的 EqualityComparer<T>”,实际上这个未公开的 System.IEquatable<T>实现内部其实使用的还是Object.Equals(Object)方法来做比较。

         这就比较郁闷了,对于Dictionary<TKey, TValue>来说,实现System.IEquatable<T>其实没什么用,始终还是要重写 Object.Equals(Object) 和 GetHashCode。

         有关的文章可以看这两篇:

         1、http://www.joycode.com/vbcti/archive/2009/02/20/115473.joy

         2、http://www.cnblogs.com/ldp615/archive/2009/09/05/1560791.html

  • 相关阅读:
    无线电频谱和波段划分
    数字IC设计工程师推荐用书
    Verilog HDL 经典用书
    Interfacing Two Clock Domains
    值得借鉴的Perl学习总结
    MIMO技术原理、概念、现状简介
    cs0016:未能写入输出文件 "c:"WINDOWS"Microsoft.NET"Framework"v2.0.50727"Temporary ASP.NET Files"root"...."*.dll“拒绝访问”
    Sql Server 2005 数据库备份还原后出现“受限制用户”问题的解决
    两个路由器连接的连接方法
    2个表之间复制数据
  • 原文地址:https://www.cnblogs.com/wenhx/p/Dictionary_IEqualityComparer.html
Copyright © 2011-2022 走看看