IEqualityComparer和Contains方法

Pab*_*uez 17 .net c# ienumerable

我有这个简单的类与2个枚举字段,我试图在集合(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,
}
Run Code Online (Sandbox Code Playgroud)

为什么可能这个测试不起作用

[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));
}
Run Code Online (Sandbox Code Playgroud)

第一个断言工作正常

Assert.IsTrue(list[1].Equals(item)) 
Run Code Online (Sandbox Code Playgroud)

但第二个没有

Assert.IsTrue(list.Contains(item));
Run Code Online (Sandbox Code Playgroud)

Nik*_*hil 23

List<T>.Contains通过使用默认的相等比较器(由其返回的那个EqualityComparer<T>.Default)来确定相等性.

这是关于如何EqualityComparer<T>.Default工作的MSDN解释:

Default属性检查类型T是否实现 System.IEquatable接口,如果是,则返回使用该实现的 EqualityComparer.否则,它返回一个EqualityComparer,它使用由T提供的Object.EqualsObject.GetHashCode的覆盖 .

换句话说,你的Calculator类要么实现System.IEquatable(没有System.IEqualityComparer!)接口或重写的Object.EqualsObject.GetHashCode方法.


D J*_*D J 5

您没有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,
}
Run Code Online (Sandbox Code Playgroud)

现在两者都应该返回true.