I have an Outer
class that contains a decimal field, called Value
. It represents a value between 0 and 1 (inclusive) and contains a logical NOT !
operator that subtracts its value from 1.
public class Outer : IEquatable<decimal> {
public decimal Value;
public Outer(decimal val = 0.5m) => Value = val;
public override string ToString() => $"Value: {Value}";
public bool Equals(Outer o) => this.Value == o.Value;
public static implicit operator decimal(Outer o) => o.Value;
public static implicit operator Outer(decimal d) => new Outer(d);
public static Outer operator !(Outer o) => new Outer(1m - Value);
}
I am attempting to compare equality (implicitly) between Outer a
and Outer b
using their Value
fields. If I initialize a
with 0.75m
, !a
should equal 0.25m
.
public class TESTING_Outer {
[NUnit.Framework.Test]
public void Not_Operator_Negates_Value() {
Outer a = 0.75m, b = 0.25m;
Assert.AreEqual(0.25m, !a); // works with direct value
Assert.AreEqual(b, (decimal)!a); // works with explicit cast
Assert.AreEqual(b, !a); // fails with implicit cast
}
}
As the comments state, this test fails when attempting to check the equality of two Outer
instances, despite them having the same value.
I get the following error output message:
Not_Operator_Negates_Value (0.045s)
---
Expected: <Value: 0.25>
But was: <Value: 0.25>
---
Why does the last Assert
fail, and how do I make sure my objects are comparing their values correctly?
CodePudding user response:
I actually stumbled upon my mistake while writing the rest of my code. Turns out I just forgot a couple of overloads.
Thank you to everyone who commented on my question. You were all quick to point out exactly what I was missing! :)
public class Outer : IEquatable<decimal> {
public decimal Value;
public Outer(decimal val = 0.5m) => Value = val;
public override string ToString() => $"Value: {Value}";
public bool Equals(Outer o) => this.Value == o.Value;
public static implicit operator decimal(Outer o) => o.Value;
public static implicit operator Outer(decimal d) => new Outer(d);
public static Outer operator !(Outer o) => new Outer(1m - Value);
// What I needed to add:
public override bool Equals(object obj) =>
obj as Outer == null ? false : (obj as Outer).Value == Value;
public override int GetHashCode() => Value.GetHashCode();
}