sgm*_*ore 28 c# linq-to-objects 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;
}
}
Run Code Online (Sandbox Code Playgroud)
Chr*_*den 54
你可以尝试类似的东西:
var differences = list2.Where(l2 =>
!list1.Any(l1 => l1.Name == l2.Name && l1.Size == l2.Size));
Run Code Online (Sandbox Code Playgroud)
或者如果您愿意:
var differences = list2.Where(l2 =>
list1.All(l1 => l1.Name != l2.Name || l1.Size != l2.Size));
Run Code Online (Sandbox Code Playgroud)
我最终使用的解决方案不能这么快地描述,但这不是我的问题,它可以实现我的期望,因为它可以重复使用,并且不限于任何特定的类。
它使用Newtonsoft.Json库将对象序列化为字符串,然后比较结果。这也具有使用匿名类和嵌套类的优势。
我假设比较的工作方式是先在两个对象上调用GetHashCode,如果它们匹配,则调用Equals,在此例程中,这意味着匹配的对象将被序列化两次。
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>());
}
}
Run Code Online (Sandbox Code Playgroud)
要使用它,您可以将Except与ExceptUsingJSonCompare交换,例如:
var differences = list2.ExceptUsingJSonCompare(list1);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
32168 次 |
| 最近记录: |