Take a look at the following test. Which method do you think fails?
public class AddressableTests
{
readonly AssetLabelReference thing = new AssetLabelReference() {labelString = "thing"};
readonly AssetLabelReference sameThing = new AssetLabelReference() {labelString = "thing"};
readonly AssetLabelReference other = new AssetLabelReference() {labelString = "other"};
[Test]
public void AssetLabelEqualsMethod()
{
Assert.IsTrue(thing.Equals(sameThing));
Assert.IsFalse(thing.Equals(other));
}
[Test]
public void AssetLabelEqualsOperator()
{
Assert.IsTrue(thing == sameThing);
Assert.IsFalse(thing == other);
}
}
They both fail, sadly. AssetLabelReference overrides GetHashCode, but it doesn’t implement an Equals method, so equivalence is tested through ReferenceEquals as usual (this surprised me, too). This could cause unexpected behavior when using AssetLabelReferences as dictionary keys or in hash sets.
I recommend implementing IEquatable so that we don’t have to explicitly reference the stringLabel inside to test equivalency.
For the time being, the following EqualityComparer can be supplied to hash sets and dictionaries to correctly test label equality.
public class AssetLabelReferenceComparer : IEqualityComparer<AssetLabelReference>
{
public bool Equals(AssetLabelReference x, AssetLabelReference y)
{
if (ReferenceEquals(x, y)) return true;
if (ReferenceEquals(x, null)) return false;
if (ReferenceEquals(y, null)) return false;
return x.labelString.Equals(y.labelString);
}
public int GetHashCode(AssetLabelReference obj)
{
return obj.GetHashCode();
}
}