分享一个比较有意思的字典相等比较扩展方法DictionaryEqual

来源:互联网 发布:深圳行知小学怎么样 编辑:程序博客网 时间:2024/05/18 23:15

在stackoverflow上看到一个比较有意思的字典相等比较扩展方法,感觉思路比较巧妙,于是在这里转载下

PS:原方法不包含IEqualityComparer<TKey> keyComparer,此处将此问题补上

/// <summary>/// 对象相等比较帮助类/// </summary>public static class EqualityComparerHelper{    /// <summary>    /// 字典相等比较,原出处 http://stackoverflow.com/questions/3928822/comparing-2-dictionarystring-string-instances    /// </summary>    /// <typeparam name="TKey"></typeparam>    /// <typeparam name="TValue"></typeparam>    /// <param name="first">用于比较的第一项</param>    /// <param name="second">用于比较的第二项</param>    /// <param name="keyComparer">当TKey为非基础数据类型,并且IDictionary在构造时未提供IEqualityComparer(SortedDictionary为IComparer),则该项必须不为null,否则比较结果必定为false</param>    /// <param name="valueComparer">当TValue为非基础数据类型时,该项必须不为null,否则比较结果必定为false</param>    /// <returns></returns>    public static bool DictionaryEqual<TKey, TValue>(        this IDictionary<TKey, TValue> first, IDictionary<TKey, TValue> second,        IEqualityComparer<TKey> keyComparer = null, IEqualityComparer<TValue> valueComparer = null)    {        if (first == second) return true;        if (first == null || second == null) return false;        if (first.Count != second.Count) return false;        valueComparer = valueComparer ?? EqualityComparer<TValue>.Default;        if (keyComparer != null)        {//如果存在keyComparer,则重新构建字典            first = new Dictionary<TKey, TValue>(first, keyComparer);            second = new Dictionary<TKey, TValue>(second, keyComparer);        }        foreach (var kvp in first)        {            TValue secondValue;            if (!second.TryGetValue(kvp.Key, out secondValue)) return false;            if (!valueComparer.Equals(kvp.Value, secondValue)) return false;        }        return true;    }}

对于实现IEqualityComparer的实现,在字典中需要注意GetHashCode的实现,即意义上相同的值其HashCode也应当一致

public class Person{    public String FirstName { get; set; }    public String LastName { get; set; }    public int Age { get; set; }}public class PersonEqualityComparer : IEqualityComparer<Person>{    public bool Equals(Person x, Person y)    {        if (x == y) return true;        if ((x == null) || (y == null)) return false;        return x.LastName == y.LastName;    }    public int GetHashCode(Person obj)    {        return obj.LastName.GetHashCode();        //return obj.GetHashCode() 在字典之类需要用到Hash值的地方不能这么写,会导致可以插入重复值    }}
测试字典键值唯一性的代码
Dictionary<Person, int> dic = new Dictionary<Person, int>(new PersonEqualityComparer());dic.Add(new Person { LastName = "Z", Age = 11 }, 10);dic.Add(new Person { LastName = "Z", Age = 21 }, 15);//ArgumentException异常,已存在具有相同键的元素



0 0
原创粉丝点击