tags:

views:

48

answers:

1

I have a class with fields ColDescriptionOne(string), ColDescriptionTwo(string) and ColCodelist(int). I want to get the Intersect of two lists of this class where the desc are equal but the codelist is different.

I can use the Where clause and get what I need. However I can't seem to make it work using a custom Comparer like this:

internal class CodeListComparer: EqualityComparer<SheetRow>
{
    public override bool Equals(SheetRow x, SheetRow y)
    {
        return Equals(x.ColDescriptionOne, y.ColDescriptionOne) &&
               Equals(x.ColDescriptionSecond, y.ColDescriptionOne)
               && !Equals(x.ColCodelist, y.ColCodelist);
    }

    public override int GetHashCode(SheetRow obj)
    {
        return ((obj.ColDescriptionOne.GetHashCode()*397) + (obj.ColDescriptionSecond.GetHashCode()*397)
                + obj.ColCodelist.GetHashCode());            
    }
}

And then use it like this:

var onylByCodeList = firstSheet.Entries.Intersect(otherSheet.Entries, new CodeListComparer());

Any ideas what I'm doing wrong here ?

thanks Sunit

+2  A: 

You have a typo in the Equals method. The second line is comparing ColDescriptionOne to ColDescriptionSecond. They should both be ColDescriptionSecond.

return Equals(x.ColDescriptionOne, y.ColDescriptionOne) 
       && Equals(x.ColDescriptionSecond, y.ColDescriptionSecond)
       && !Equals(x.ColCodelist, y.ColCodelist);

The second problem you have is you are including the ColCodeList in the GetHashCode method. The GetHashCode method must return the same value for objects that are equal. In this case though ColCodeList is supposed to be different when values are equal. This means that in cases where you want 2 objects to be considered equal they are more likely to have different hash codes which is incorrect.

Take that out of the GetHashCode method and everything should work.

public override int GetHashCode(SheetRow obj)
{
    return ((obj.ColDescriptionOne.GetHashCode()*397) 
           + (obj.ColDescriptionSecond.GetHashCode()*397));
}
JaredPar
Sorry...but that was dumb of me! I did change but still not able to get it. Maybe I'm missing something else...
Sunit
Thanks...You are very right. I totally missed that.
Sunit
Quick question, if I need to report values from both objects that pass the Comparer above, I guess I'll need right a custom extension with GetEnumerators()...right ?
Sunit