Linq除外,带有自定义IEqualityComparer [英] Linq Except with custom IEqualityComparer

查看:100
本文介绍了Linq除外,带有自定义IEqualityComparer的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正尝试找出两个通用列表之间的区别,如下例所示. 即使t1和t2包含相同的属性,它们也不是同一对象,所以我必须实现IEqualityComparer.

I am trying to find the difference between two generic lists, as in the example below. Even though t1 and t2 contain the same properties, they are not the same object, so I have need to implement an IEqualityComparer.

这似乎适用于本示例,但是真实类具有其他一些属性,我还需要对其他一些类进行相同的操作.

This appears to be working with this example, but the real class has several other properties and I also need to do the same with a few other class.

所以我想知道我是否正在重新发明轮子吗?

So I was wondering if I am re-inventing the wheel?

是否有比较简单的方法来比较两个对象的所有属性?此刻,我真的只需要处理包含简单类型的类,但是很高兴我有一个比较器可以处理包含其他类实例的类.

Is there an easier method of comparing all the properties of two objects? At the moment, I really only need to cope with class containing simple types, but it would be nice I have a comparer that worked with classes that contains instances of other classes.

void Main()
{
    var t1 = new Sizes { Name = "Test" , Size = 1} ;
    var t2 = new Sizes { Name = "Test" , Size = 1} ;

    var list1 = new List<Sizes>();
    var list2 = new List<Sizes>();
    list1.Add(t1);
    list2.Add(t2);

    var differences = list2.Except(list1 , new SizesComparer());    
    // differences should be empty.
}


public class Sizes  
{
    public string Name { get;  set; }
    public int    Size { get;  set; }
}

public class SizesComparer : IEqualityComparer<Sizes>   
{
    bool IEqualityComparer<Sizes>.Equals(Sizes x, Sizes y)
    {            
        return (x.Name.Equals(y.Name) && x.Size.Equals(y.Size));        
    }

    int IEqualityComparer<Sizes>.GetHashCode(Sizes obj)
    {
        if (Object.ReferenceEquals(obj, null))
            return 0;               

        return obj.Name.GetHashCode() + obj.Size;       
    }
}

推荐答案

我最终使用的解决方案不能被描述为快速的解决方案,但这不是我的问题,它可以满足我的要求可以重复使用,并且不限于任何特定的类.

The solution which I ended up using could not be described as fast, but that is not a concern of mine and it does what I want in that it can be re-used and is not restricted to any particular class.

它使用Newtonsoft.Json库将对象序列化为字符串,然后比较结果.这也具有使用匿名类和嵌套类的优势.

It uses the Newtonsoft.Json library to serialize the object to a string and then compares the result. This also has the advantage of working with anonymous classes and nested classes.

我假设比较的工作方式是先在两个对象上调用GetHashCode,如果它们匹配,则调用Equals,在此例程中,这意味着匹配的对象将被序列化两次.

I am assuming that the way the comparison works is that it first calls GetHashCode on both objects and if they match it then calls Equals, which in this routine will mean that matching objects will be serialized twice.

public class JSonEqualityComparer<T> : IEqualityComparer<T>
{   
    public bool Equals(T x, T y)
    {           
        return String.Equals
        ( 
            Newtonsoft.Json.JsonConvert.SerializeObject(x), 
            Newtonsoft.Json.JsonConvert.SerializeObject(y)
        );                  
    }

    public int GetHashCode(T obj)
    {                           
        return Newtonsoft.Json.JsonConvert.SerializeObject(obj).GetHashCode();          
    }               
}       


public static partial class LinqExtensions
{
    public static IEnumerable<T> ExceptUsingJSonCompare<T>
        (this IEnumerable<T> first, IEnumerable<T> second)
    {   
        return first.Except(second, new JSonEqualityComparer<T>());
    }
}

要使用它,您可以将Except与ExceptUsingJSonCompare交换,例如:

To use it you swap Except with ExceptUsingJSonCompare, for example :

var differences = list2.ExceptUsingJSonCompare(list1); 

这篇关于Linq除外,带有自定义IEqualityComparer的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆