IEqualityComparer<T> VS System.IEquatable<T>

类似于IComparer<T> VS IComparable<T>.

public interface IComparable<in T>

{    // Methods    

    int CompareTo(T other);

}

public interface IComparer<in T>

{    // Methods    

    int Compare(T x, T y);

}

public interface IEquatable<T>

{    // Methods    

    bool Equals(T other);

}

public interface IEqualityComparer<in T>

{    // Methods   

    bool Equals(T x, T y);    

    int GetHashCode(T obj);

}

IEqualityComparer<T>是用于custom 比较是否相等的,而System.IEquatable<T>是用于default 比较的。即某个class 会实现 IEquatable<T>来定义相等操作,而 IEqualityComparer<T> 则用于自定义判断。例如用在LinkedList.Find(T value)方法中。

EqualityComparer<T> comparer = EqualityComparer<T>.Default;

以string 类为例来说明:

public sealed class String : IComparable, ICloneable, IConvertible, IComparable<string>, IEnumerable<char>, IEnumerable, IEquatable<string>

例如Dictionary<TKey, TValue>的key 不可以重复,当调用Add方法时就会判断是否相等。

对比Container类的构造函数:

public Dictionary(int capacity, IEqualityComparer<TKey> comparer); //Dictionary需要对key进行判断是否相等的操作所以需要实现IEqualityComparer接口的对象

public LinkList();  //不需要sort,也不需要判断添加的对象是否相等所以不需要comparer

public List(); 动态数组. 仅在sort方法中需要提供一个comparer对象,如果没有则使用集合中存储对象默认的比较方法即要求被存储类必须实现IComparable接口

public BinarySearchTree(IComparer<T> comparer);  二叉树需要对添加的元素进行比较。 this.comparer = Comparer<T>.Default;

public SortSet(IComparer<T> comparer);  红黑树也需要对添加的元素进行比较

using System;
    using System.Collections.Generic;

    class Program
    {
        static Dictionary<Box, String> boxes;

        static void Main(string[] args)
        {

            BoxSameDimensions boxDim = new BoxSameDimensions();
            boxes = new Dictionary<Box, string>(boxDim);

            Console.WriteLine("Boxes equality by dimensions:");
            Box redBox = new Box(8, 4, 8);
            Box greenBox = new Box(8, 6, 8);
            Box blueBox = new Box(8, 4, 8);
            Box yellowBox = new Box(8, 8, 8);
            AddBox(redBox, "red");
            AddBox(greenBox, "green");
            AddBox(blueBox, "blue");
            AddBox(yellowBox, "yellow");

            Console.WriteLine();
            Console.WriteLine("Boxes equality by volume:");

            BoxSameVolume boxVolume = new BoxSameVolume();
            boxes = new Dictionary<Box, string>(boxVolume);
            Box pinkBox = new Box(8, 4, 8);
            Box orangeBox = new Box(8, 6, 8);
            Box purpleBox = new Box(4, 8, 8);
            Box brownBox = new Box(8, 8, 4);
            AddBox(pinkBox, "pink");
            AddBox(orangeBox, "orange");
            AddBox(purpleBox, "purple");
            AddBox(brownBox, "brown");
        }

        public static void AddBox(Box bx, string name)
        {
            try
            {
                boxes.Add(bx, name);
                Console.WriteLine("Added {0}, Count = {1}, HashCode = {2}",
                    name, boxes.Count.ToString(), bx.GetHashCode());
            }
            catch (ArgumentException)
            {
                Console.WriteLine("A box equal to {0} is already in the collection.", name);
            }

 


        }
    }
    public class Box
    {
        public Box(int h, int l, int w)
        {
            this.Height = h;
            this.Length = l;
            this.Width = w;
        }
        public int Height { get; set; }
        public int Length { get; set; }
        public int Width { get; set; }
    }


    class BoxSameDimensions : EqualityComparer<Box>
    {

        public override bool Equals(Box b1, Box b2)
        {
            if (b1.Height == b2.Height & b1.Length == b2.Length
                                & b1.Width == b2.Width)
            {
                return true;
            }
            else
            {
                return false;
            }
        }


        public override int GetHashCode(Box bx)
        {
            int hCode = bx.Height ^ bx.Length ^ bx.Width;
            return hCode.GetHashCode();
        }

    }

    class BoxSameVolume : EqualityComparer<Box>
    {

        public override bool Equals(Box b1, Box b2)
        {
            if (b1.Height * b1.Width * b1.Length ==
                b2.Height * b2.Width * b2.Length)
            {
                return true;
            }
            else
            {
                return false;
            }
        }


        public override int GetHashCode(Box bx)
        {
            int hCode = bx.Height ^ bx.Length ^ bx.Width;
            return hCode.GetHashCode();
        }

    }
    /* This example produces the following output:
     * 
        Boxes equality by dimensions:
        Added red, Count = 1, HashCode = 46104728
        Added green, Count = 2, HashCode = 12289376
        A box equal to blue is already in the collection.
        Added yellow, Count = 3, HashCode = 55530882

        Boxes equality by volume:
        Added pink, Count = 1, HashCode = 30015890
        Added orange, Count = 2, HashCode = 1707556
        A box equal to purple is already in the collection.
        A box equal to brown is already in the collection.
     * 
    */


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值