Oliver Vogel
Oliver Vogel

Reputation: 1998

LINQ Distinct not working as expected

I have the following simple class

public class Person : IEquatable<Person>
{
    public bool Equals(Person other) 
    {
        return Name.Equals(other.Name, StringComparison.InvariantCultureIgnoreCase);
    }

    public override int GetHashCode()
    {
        return Name.GetHashCode();
    }

    public Person(string name)
    {
        Name = name;
    }
    public string Name { get; set; }
}

Now I am creating an array of persons, calling distinct on them and pass the default Equality Comparer, which is the one implemented by IEquatable<Person>

var persons = new[] {new Person("foo"), new Person("Foo"), new Person("bar"), new Person("Bar")};
persons.Distinct(EqualityComparer<Person>.Default);

When I inspect the distincted persons, I am expecting an IEnumerable<Person> containing foo, bar. However the contents are foo, Foo, bar, Bar

When I initialize the List with foo, foo, bar, bar the result is as expected. So it seems to me as if StringComparison.InvariantCultureIgnoreCase in the Person.Equals method is ignored.

Has anyone an idea?

Upvotes: 3

Views: 1790

Answers (2)

DaveShaw
DaveShaw

Reputation: 52788

You need to make GetHashCode() get a case-*in*sensitive Hash Code at the moment, it will be a different hash code for upper and lower case Name's.

For example:

public override int GetHashCode() 
{ 
    return Name.ToUpperInvariant().GetHashCode(); 
} 

Upvotes: 3

JacquesB
JacquesB

Reputation: 42639

Your GetHashCode() will return different hash codes for objects who should be considered identical.

Upvotes: 2

Related Questions