C# 比较两个集合值c

C# 比较两个集合值c,c#,.net,generics,collections,reference,C#,.net,Generics,Collections,Reference,我有两个集合具有相同的值,但它们具有不同的引用。在没有foreach语句的情况下,比较两个集合的最佳方法是什么, 下面是我创建的示例应用程序 using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; namespace CollectionComparer { public class Program { private sta

我有两个集合具有相同的值,但它们具有不同的引用。在没有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和比较特定类型属性的情况下进行此类比较。

您可以使用IComparable接口并实现自己的比较功能。您可以参考以下链接

您可以使用iComparable界面并实现自己的比较功能。您可以参考以下链接

您可以先使用Enumerable.SequenceEqualEnumerable,然后使用IEnumerable

这将按顺序比较两个序列,如果其中包含的项相等,并且两个序列的元素数相同,则返回true

需要注意的是,由于Person不重写Equalsobject obj,SequenceEqual将在比较任意两个Person对象时执行默认的引用相等检查,您可能需要值相等语义。为了解决这个问题,至少要重写BoOL均衡对象Objo和int GetHashCode。 如果无法修改Person,则可以定义自己的IEqualityComparer并将其交给SequenceEquals,以便它可以执行除默认引用相等之外的相等检查

更新:如果订单不重要,则可以使用和。这可以很快地慢下来,所以你至少应该考虑把你比较的集合转换成之前的某个集合的可能性。

UPDATE2:Enumerable.SequenceEquals实际上是一个扩展方法,应该这样调用:p1.SequenceEqualsp2

您可以先使用Enumerable.SequenceEqualsEnumerable,然后使用IEnumerable

这将按顺序比较两个序列,如果其中包含的项相等,并且两个序列的元素数相同,则返回true

需要注意的是,由于Person不重写Equalsobject obj,SequenceEqual将在比较任意两个Person对象时执行默认的引用相等检查,您可能需要值相等语义。为了解决这个问题,至少要重写BoOL均衡对象Objo和int GetHashCode。 如果无法修改Person,则可以定义自己的IEqualityComparer并将其交给SequenceEquals,以便它可以执行除默认引用相等之外的相等检查

更新:如果订单不重要,则可以使用和。这可以很快地慢下来,所以你至少应该考虑把你比较的集合转换成之前的某个集合的可能性。


UPDATE2:Enumerable.SequenceEquals实际上是一个扩展方法,应该这样调用:p1.SequenceEqualsp2

您可以为Person类重写Equals为什么不想使用foreach循环?for循环呢?顺序重要吗?还是要检查这两个集合中的人员是否按任意顺序相同?例如,您有两个列表p1和p2。var areEqual=p1.Allp=>p2.Containsp;这里的秩序并不重要。我只想检查一个项目是否在一个集合中添加、删除或编辑。您可以为Person类重写等于为什么不想使用foreach循环?for循环呢?顺序重要吗?还是要检查这两个集合中的人员是否按任意顺序相同?例如,您有两个列表p1和p2。var areEqual=p1.Allp=>p2.Containsp;这里的秩序并不重要。我只是想检查一个项目是否在一个集合中添加、删除或编辑。我认为上面的代码可以使用,但上面的场景两个集合顺序应该相同。但在我的集合中,顺序可能会有所不同。感谢您的帮助,当我有值类型时,这项功能可以正常工作,但对引用类型属性不起作用。如果我将Id更改为Guid,则在同一个人类中创建一个示例。这一比较是有效的。我认为上面的代码可以使用,但是上面的场景两个收集序列应该是相同的。但在我的集合中,顺序可能会有所不同。感谢您的帮助,当我有值类型时,这项功能可以正常工作,但对引用类型属性不起作用。如果我将Id更改为Guid,则在同一个人类中创建一个示例。这一比较是有效的。有没有办法绕过这件事。
public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
    public string Country { get; set; }

    public override bool Equals(object obj)
    {
         var person = obj as Person;

         if (person == null) return false;

         return person.Id == Id && person.Name = Name && //etc.
    }

    public override int GetHashCode() 
        => Id.GetHashCode() ^ Name.GetHashCode() ^ //etc.
}