Метод IEqualityComparer и Содержит
У меня есть этот простой класс с этими 2 полями enum, я пытаюсь найти один элемент этого объекта в коллекции (List<T>
), но методы Contains не работают правильно
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,
}
Почему может быть, что этот тест не работает?
[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));
}
Первое утверждение отлично работает
Assert.IsTrue(list[1].Equals(item))
но второй не
Assert.IsTrue(list.Contains(item));
Ответы
Ответ 1
List<T>.Contains
определяет равенство, используя сопоставитель равенства по умолчанию (тот, который возвращается EqualityComparer<T>.Default
).
Здесь объясняется сообщение MSDN о том, как EqualityComparer<T>.Default
:
Свойство Default проверяет, реализует ли тип T System.IEquatable и, если это так, возвращает EqualityComparer, который использует эту реализацию. В противном случае возвращает EqualityComparer, в котором используются переопределения Object.Equals и Object.GetHashCode предоставлены T.
Другими словами, ваш класс Calculator
должен либо реализовать интерфейс System.IEquatable ( не System.IEqualityComparer
!), либо переопределите методы Object.Equals и Object.GetHashCode.
Ответ 2
Вы не используете IEqualityComparer<Calculator>
в Equals и Содержите оба. EqualityComparer
имеет другое значение. Я исправил код для вас.
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,
}
Теперь оба должны вернуть true.