I have this simple class with those 2 enum fields, I'm trying to find one item of this object in a collection (List<T>
) but the Contains methods doesn't works correctly
public class Calculator : IEqualityComparer<Calculator>
{
public DashboardsComputationMode ComputationMode { get; set; }
public Modes Mode { get; set; }
public Calculator(DashboardsComputationMode dashboardsComputationMode, Modes mode)
{
ComputationMode = dashboardsComputationMode;
Mode = mode;
}
public bool Equals(Calculator x, Calculator y)
{
return (x.ComputationMode.Equals(y.ComputationMode) && x.Mode.Equals(y.Mode));
}
public int GetHashCode(Calculator obj)
{
return obj.ComputationMode.GetHashCode() ^ obj.Mode.GetHashCode();
}
}
public enum DashboardsComputationMode
{
Weighted = 0,
Aggregated = 1,
PR = 2,
CurrentValue = 3,
EquivalentHours = 4,
AggregatedCorrected = 5,
PRCorrected = 6
}
public enum Modes
{
InstantaneousMode = 0,
DailyMode = 1,
MonthlyMode = 2,
YearlyMode = 5,
Undefined = 4,
}
Why could be that this test doesn't works
[TestMethod]
public void TestMethod1()
{
var list = new List<Calculator>()
{
new Calculator(DashboardsComputationMode.PR, Modes.DailyMode),
new Calculator(DashboardsComputationMode.CurrentValue, Modes.YearlyMode),
new Calculator(DashboardsComputationMode.PRCorrected, Modes.MonthlyMode)
};
var item = new Calculator(DashboardsComputationMode.CurrentValue, Modes.YearlyMode);
Assert.IsTrue(list[1].Equals(item));
Assert.IsTrue(list.Contains(item));
}
The first assert works fine
Assert.IsTrue(list[1].Equals(item))
but the second doesn't
Assert.IsTrue(list.Contains(item));
IEqualityComparer<T> is a generic . NET interface that allows implementing customized equality comparison for collections. Creating a comparer class for your type is an alternative to creating Equals() and GetHashCode() methods for the type.
List<T>.Contains
determines equality by using the default equality comparer (the one returned by the EqualityComparer<T>.Default
).
Here's the MSDN explanation on how EqualityComparer<T>.Default
works:
The Default property checks whether type T implements the System.IEquatable interface and, if so, returns an EqualityComparer that uses that implementation. Otherwise, it returns an EqualityComparer that uses the overrides of Object.Equals and Object.GetHashCode provided by T.
In other words, your Calculator
class should either implement the System.IEquatable (not the System.IEqualityComparer
!) interface or override the Object.Equals and Object.GetHashCode methods.
You are not using IEqualityComparer<Calculator>
in Equals and Contains both. EqualityComparer
has a different significance. I corrected the code for you.
public class CalculatorComparer : IEqualityComparer<Calculator>
{
public bool Equals(Calculator x, Calculator y)
{
return (x.ComputationMode.Equals(y.ComputationMode) && x.Mode.Equals(y.Mode));
}
public int GetHashCode(Calculator obj)
{
return obj.ComputationMode.GetHashCode() ^ obj.Mode.GetHashCode();
}
}
public class Calculator
{
public DashboardsComputationMode ComputationMode { get; set; }
public Modes Mode { get; set; }
public Calculator(DashboardsComputationMode dashboardsComputationMode, Modes mode)
{
ComputationMode = dashboardsComputationMode;
Mode = mode;
}
public override bool Equals(object obj)
{
Calculator y = obj as Calculator;
return (this.ComputationMode.Equals(y.ComputationMode) && this.Mode.Equals(y.Mode));
}
}
public enum DashboardsComputationMode
{
Weighted = 0,
Aggregated = 1,
PR = 2,
CurrentValue = 3,
EquivalentHours = 4,
AggregatedCorrected = 5,
PRCorrected = 6
}
public enum Modes
{
InstantaneousMode = 0,
DailyMode = 1,
MonthlyMode = 2,
YearlyMode = 5,
Undefined = 4,
}
Now both should return true.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With