Linq except 使用自定义 IEqualityComparer
我试图找出两个通用列表之间的差异,如下例所示。 尽管 t1 和 t2 包含相同的属性,但它们不是同一个对象,因此我需要实现 IEqualityComparer。
这似乎适用于这个示例,但真正的类有几个其他属性,我还需要对其他一些类执行相同的操作。
所以我想知道我是否在重新发明轮子?
有没有更简单的方法来比较两个对象的所有属性?目前,我实际上只需要处理包含简单类型的类,但如果我有一个可以处理包含其他类实例的类的比较器,那就太好了。
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;
}
}
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;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以尝试以下操作:
或者如果您愿意:
You could try something like:
Or if you prefer:
我最终使用的解决方案不能被描述为快速,但这不是我关心的问题,它满足我的要求,因为它可以重复使用并且不限于任何特定的类。
它使用 Newtonsoft.Json 库将对象序列化为字符串,然后比较结果。这也具有使用匿名类和嵌套类的优点。
我假设比较的工作方式是,它首先对两个对象调用 GetHashCode,如果它们匹配,则调用 Equals,这在此例程中意味着匹配的对象将被序列化两次。
要使用它,请将 except 与 exceptUsingJSonCompare 交换,例如:
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.
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.
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.
To use it you swap Except with ExceptUsingJSonCompare, for example :