I'm trying to store (name: string, value: long) pair in a set.
public class NameValuePair
{
public string name;
public long value;
}
public NameValuePairComparer comparer = new NameValuePairComparer();
public HashSet<NameValuePair> nameValueSet = new HashSet<NameValuePair>(comparer);
Two pairs are equal if either they have equal name or equal value - this is implemented in NameValuePairComparer overriding Equals method from EqualityComparer:
public class NameValuePairComparer : EqualityComparer<NameValuePair>
{
public override bool Equals(NameValuePair x, NameValuePair y)
{
return (x.value == y.value) || (x.name == y.name);
}
The problem is: GetHashCode(NameValuePair obj) should return the same value for two objects for which Equals return true, so for given NameValuePair, GetHashCode() should return either value.GetHashCode() or name.GetHashCode(), but to do this we have to know which field in both pairs is equal:
public override int GetHashCode(NameValuePair obj)
{
/* ??? */
/* // Using unknown reference to x
if (obj.value == x.value) return obj.value.GetHashCode();
else if (obj.name == x.name) return obj.name.GetHashCode();
else return base.GetHashCode(obj);
*/
}
}
But we can't know this, and that means I can't use HashSet to store these pairs nor EqualityComparer.
Q: Is there not-hash-based implementation of set in C# (.net 3.5) ?
Q: What would be better approach to storing unique NameValuePairs with custom equality comparer ?