c # Пересекает 2 списка с одинаковыми, но неидентичными объектами

#c# #linq #intersect

#c# #linq #пересекать

Вопрос:

Я хочу пересечь 2 списка объектов, которые имеют одинаковые типы и одинаковые свойства, но объекты в списке были созданы отдельно.

 class foo
{ 
  int id;
  string name;

  public foo(int Id, string Name)
  {
     id = Id;
     name = Name;
  }
}
  
 List<foo> listA = new List<foo>() {new foo(1, "A"), new foo(2, "B"), new foo(3, "C")};
List<foo> listB = new List<foo>() {new foo(2, "B"), new foo(3, "C"), new foo(4, "D")};

List<foo> intersect = listA.Intersect(listB).ToList();
  

foo object B amp; C находятся в listA и listB, но когда я их пересекаю, я получаю 0 записей. Я знаю это, потому что нет одного и того же объекта, но что мне нужно сделать, чтобы получить список с B и C в любом случае?. Чего мне не хватает?

Комментарии:

1. Вы не переопределяете Equals или GetHashCode . Если вы переопределите их, чтобы указать, когда вы считаете, что разные объекты равны, код будет работать без каких-либо других изменений. Или вы можете создать IEqualityComparer<foo> и передать это Intersect методу в качестве второго аргумента. (Кроме того, лучше всего сделать так, чтобы пример кода соответствовал обычным соглашениям об именовании .NET, где имена классов являются PascalCased, а имена параметров — camelCased.)

2. Если они не являются одним и тем же экземпляром , что определяет, что они одинаковы ? Это id ?

3. @Martin я не уверен на 100%, достаточно ли Id, но, по крайней мере, Id должен быть равен.

Ответ №1:

Вы можете переопределить, как .NET «решает», равны ли объекты — переопределив Equals и GetHashCode .

Visual Studio может помочь в этом: https://learn.microsoft.com/en-us/visualstudio/ide/reference/generate-equals-gethashcode-methods?view=vs-2019

Комментарии:

1. мне удалось переопределить метод Equals, но я не уверен, как переопределить GetHashCode()

2. Помогает ли статья, на которую я ссылался в ответе? Visual Studio может автоматически сгенерировать его. Кроме того, вы можете взглянуть на другие примеры здесь: learn.microsoft.com/en-us/dotnet/api /…

Ответ №2:

Для всех, кому это нужно. Я взял ответ @arconaut и добавил его в свой код, так что теперь foo выглядит так:

    class foo
   {
      int id;
      string name;
      public foo(int Id, string Name)
      {
         id = Id;
         name = Name;
      }
      public override bool Equals(object obj)
      {
         return Equals(obj as foo);
      }

      public bool Equals(foo obj)
      {
         if (obj == null) return false;
         return (id == obj.id amp;amp; name == obj.name);
      }

      public override int GetHashCode()
      {
         var hashCode = 352033288;
         hashCode = hashCode * -1521134295   id.GetHashCode();
         hashCode = hashCode * -1521134295   name.GetHashCode();
         return hashCode;
      }
   }
  

Я все еще не уверен в хэш-коде, но он работает. итак, спасибо