I have a case where I need to grab a bunch of items on distinct, but my source is a collection of objects with two properties, like this:
public class SkillRequirement
{
public string Skill { get; set; }
public string Requirement { get; set; }
}
I try to get a collection as follows:
SkillRequirementComparer sCom = new SkillRequirementComparer();
var distinct_list = source.Distinct(sCom);
I tried to implement an IEqualityComparer<T>
for this, but I fell stumped at the GetHashCode()
method.
The class for the Comparer:
public class SkillRequirementComparer : IEqualityComparer<SkillRequirement>
{
public bool Equals(SkillRequirement x, SkillRequirement y)
{
if (x.Skill.Equals(y.Skill) && x.Requirement.Equals(y.Requirement))
{
return true;
}
else
{
return false;
}
}
public int GetHashCode(SkillRequirement obj)
{
//?????
}
}
Normally I would just use GetHashCode()
on a property, but because I am comparing on two properties, I'm a bit at a loss of what to do. Am I doing anything wrong, or missing something really obvious?
You can implement GetHashCode
in the following way:
public int GetHashCode(SkillRequirement obj)
{
unchecked
{
int hash = 17;
hash = hash * 23 + obj.Skill.GetHashCode();
hash = hash * 23 + obj.Requirement.GetHashCode();
return hash;
}
}
originally from J.Skeet
If the properties can be null
you should avoid a NullReferenceException
, e.g.:
int hash = 17;
hash = hash * 23 + (obj.Skill ?? "").GetHashCode();
hash = hash * 23 + (obj.Requirement ?? "").GetHashCode();
return hash;
I would like to link the following stack overflow posts too though the question is already answered..
GetHashCode -
Why is it important to override GetHashCode when Equals method is overridden?
Also, in the above answer Tim Schmelter says the properties can be null you should avoid a NullReferenceException
int hash = 17;
hash = hash * 23 + (obj.Skill ?? "").GetHashCode();
hash = hash * 23 + (obj.Requirement ?? "").GetHashCode();
return hash;
IEqualityComparer -
- What is the difference between using IEqualityComparer and Equals/GethashCode Override
- What's the role of GetHashCode in the IEqualityComparer in .NET?
- How and when to use IEqualityComparer in C#
IEquatable - What's the difference between IEquatable and just overriding Object.Equals()?
Equals - Guidelines for Overloading Equals()
class TwoDPoint : System.Object
{
public readonly int x, y;
public TwoDPoint(int x, int y) //constructor
{
this.x = x;
this.y = y;
}
public override bool Equals(System.Object obj)
{
// If parameter is null return false.
if (obj == null)
{
return false;
}
// If parameter cannot be cast to Point return false.
TwoDPoint p = obj as TwoDPoint;
if ((System.Object)p == null)
{
return false;
}
// Return true if the fields match:
return (x == p.x) && (y == p.y);
}
public bool Equals(TwoDPoint p)
{
// If parameter is null return false:
if ((object)p == null)
{
return false;
}
// Return true if the fields match:
return (x == p.x) && (y == p.y);
}
public override int GetHashCode()
{
//return x ^ y;
}
}