两个列表之间相交不起作用

时间:2011-11-29 17:03:29

标签: c# linq list

我有两个列表见下面......结果是空的

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);

任何线索为什么?

4 个答案:

答案 0 :(得分:24)

您需要覆盖Equals类中的GetHashCodePay方法,否则Intersect不知道2个实例何时被视为相等。怎么可能猜到EventId决定了平等呢? <{1}}和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

答案 1 :(得分:0)

Intersect可能只会在同一个Pay实例同时List中添加对象。当oldPaynewPay被实例化时,它们被认为是不相等的。

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)
   }

答案 2 :(得分:0)

对象是引用类型。创建两个对象时,您有两个唯一引用。他们比较平等的唯一方法就是你做了:

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

在这种情况下,(a == b)为真。阅读referencevalue类型和objects

要修复你的问题,请改写Equals和GetHashCode,正如Thomas Levesque指出的那样。

答案 3 :(得分:0)

正如其他人指出的那样,您需要提供适当的替代,以使Intersect正常工作。但是,如果您不想打扰覆盖并且用例很简单,则还有另一种方法。假设您要匹配EventId上的项目,但是您可以对其进行修改以比较任何属性。请注意,这种方法可能比调用Intersect更为昂贵,但对于较小的数据集则可能没有关系。

List<Pay> intersectedPays = new List<Pay>();

foreach (Pay o in olist)
{
    var intersectedPay = nlist.Where(n => n.EventId == o.EventId).SingleOrDefault();

    if (intersectedPay != null)
        intersectedPays.Add(intersectedPay);
}

List<Pay> result = intersectedPays;