Пересечение между двумя списками не работает
У меня есть два списка, см. ниже..... результат возвращается как пустой
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, как указал Томас Левеск.