我有两个集合具有相同的值,但它们具有不同的引用。如果没有foreach语句,比较两个集合的最佳方法是什么?下面是我创建的示例应用程序,
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
namespace CollectionComparer
{
public class Program
{
private static void Main(string[] args)
{
var persons = GetPersons();
var p1 = new ObservableCollection<Person>(persons);
IList<Person> p2 = p1.ToList().ConvertAll(x =>
new Person
{
Id = x.Id,
Age = x.Age,
Name = x.Name,
Country = x.Country
});
//p1[0].Name = "Name6";
//p1[1].Age = 36;
if (Equals(p1, p2))
Console.WriteLine("Collection and its values are Equal");
else
Console.WriteLine("Collection and its values are not Equal");
Console.ReadLine();
}
public static IEnumerable<Person> GetPersons()
{
var persons = new List<Person>();
for (var i = 0; i < 5; i++)
{
var p = new Person
{
Id = i,
Age = 20 + i,
Name = "Name" + i,
Country = "Country" + i
};
persons.Add(p);
}
return persons;
}
}
}
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public string Country { get; set; }
}
在上面的代码中,我需要比较集合p1和p2。但结果总是“集合及其值不相等”,因为两个集合的引用不同。有没有一种通用的方法来进行这种比较,而不使用foreach和比较类型特定的属性。
3条答案
按热度按时间sqougxex1#
可以使用
Enumerable.SequenceEqual<T>(IEnumerable<T> first, IEnumerable<T> second)
。这将比较两个序列 in order,并返回
true
,如果其中包含的项相等,并且两者具有相同数量的元素。需要注意的是,因为
Person
不会覆盖Equals(object obj)
,所以在比较任何两个Person
对象时,SequenceEqual
将执行默认的 * 引用相等检查 *,并且您可能需要值相等语义。要解决这个问题,至少要重写bool Equals(object obj)
和int GetHashCode()
(也实现IEquatable<Person>
被认为是一个好的实践):如果不能修改
Person
,那么可以定义自己的IEqualityComparer<Person>
并将其交给SequenceEquals
,以便它可以执行除默认引用相等性之外的相等性检查。Union
和Except
。这可能会变得非常慢,所以您至少应该考虑将正在比较的集合转换为某种类型的Set
的可能性。Enumerable.SequenceEqual
实际上是一个 extension 方法,应该这样调用:p1.SequenceEquals(p2)
5n0oy7gb2#
您可以使用IComareable接口并实现自己的比较函数。您可以参考以下链接https://msdn.microsoft.com/de-de/library/system.icomparable(v=vs.110).aspx
3pmvbmvn3#
我知道这很老了,但也许我能让某人的日子更轻松。在寻找一种方法来比较两个ObservableCollections(其中T具有许多属性)之后,我的最终解决方案是JSON序列化两个对象并比较字符串结果。这对我来说工作得很好,只需要很少的代码。当然,在我的情况下,收集开始时是相同的,我只对为标记脏状态而进行的编辑感兴趣。