Пересечение между двумя списками не работает

У меня есть два списка, см. ниже..... результат возвращается как пустой

List<Pay>olist = new List<Pay>();
List<Pay> nlist = new List<Pay>();
Pay oldpay = new Pay()
{
    EventId = 1,
    Number = 123,                        
    Amount = 1
};

olist.Add(oldpay);
Pay newpay = new Pay ()
{
   EventId = 1,
    Number = 123,                        
    Amount = 100
};
nlist.Add(newpay);
var Result = nlist.Intersect(olist);

какая-нибудь подсказка почему?

Ответ 1

Вам необходимо переопределить методы Equals и GetHashCode в вашем классе Pay, иначе Intersect не знает, когда два экземпляра считаются равными. Как он мог предположить, что именно EventId определяет равенство? oldPay и newPay - разные экземпляры, поэтому по умолчанию они не считаются равными.

Вы можете переопределить методы в Pay следующим образом:

public override int GetHashCode()
{
    return this.EventId;
}

public override bool Equals(object other)
{
    if (other is Pay)
        return ((Pay)other).EventId == this.EventId;
    return false;
}

Другой вариант - реализовать IEqualityComparer<Pay> и передать его как параметр в Intersect:

public class PayComparer : IEqualityComparer<Pay>
{
    public bool Equals(Pay x, Pay y)
    {
        if (x == y) // same instance or both null
            return true;
        if (x == null || y == null) // either one is null but not both
            return false;

        return x.EventId == y.EventId;
    }


    public int GetHashCode(Pay pay)
    {
        return pay != null ? pay.EventId : 0;
    }
}

...

var Result = nlist.Intersect(olist, new PayComparer());

Ответ 2

Intersect, вероятно, только добавляет объекты, когда один и тот же экземпляр Pay находится в обоих List. Поскольку oldPay и newPay создаются отдельно, они считаются не равными.

Intersect использует метод Equals для сравнения объектов. Если вы не переопределяете его, он сохраняет одно и то же поведение класса Object: возвращает true только в том случае, если оба являются одним и тем же экземпляром объекта.

Вы должны переопределить метод Equals в Pay.

   //in the Pay class
   public override bool Equals(Object o) {
      Pay pay = o as Pay;
      if (pay == null) return false;
      // you haven't said if Number should be included in the comparation
      return EventId == pay.EventId; // && Number == pay.Number; (if applies)
   }

Ответ 3

Объекты являются ссылочными типами. Когда вы создаете два объекта, у вас есть две уникальные ссылки. Единственный способ, которым они когда-либо сравнивали бы равные, - это:

object a = new object();
object b = a;

В этом случае (a == b) истинно. Прочитайте reference vs значение, а объекты

И чтобы исправить вашу проблему, переопределите Equals и GetHashCode, как указал Томас Левеск.