Метод IEqualityComparer и Содержит - программирование
Подтвердить что ты не робот

Метод 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));
4b9b3361

Ответ 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.