的IEqualityComparer和包含的方法方法、IEqualityComparer

2023-09-03 12:43:41 作者:第一眼沦陷

我有这个简单的类与2枚举领域,我试图找到这个对象的一个​​项目在一个集合(名单,其中,T> ),但包含方法不能正常工作

 公共类计算器:的IEqualityComparer<计算器>
{
    公共DashboardsComputationMode ComputationMode {获得;组; }
    公共模式模式{获得;组; }

    公共计算器(DashboardsComputationMode dashboardsComputationMode,模式模式)
    {
        ComputationMode = dashboardsComputationMode;
        模式=方式;
    }

    公共布尔等于(计算机X,计算器Y)
    {
        返程(x.ComputationMode.Equals(y.ComputationMode)及和放大器; x.Mode.Equals(y.Mode));
    }

    公众诠释GetHash code(计算器OBJ)
    {
        返回obj.ComputationMode.GetHash code()^ obj.Mode.GetHash code();
    }
}

公共枚举DashboardsComputationMode
{
    加权= 0,
    凝集= 1,
    PR = 2,
    CurrentValue的= 3,
    EquivalentHours = 4,
    AggregatedCorrected = 5,
    PRCorrected = 6
}

公共枚举模式
{
    InstantaneousMode = 0,
    DailyMode = 1,
    MonthlyMode = 2,
    YearlyMode = 5,
    未定义= 4,
}
 

为什么可能是本次测试没有作品

  [TestMethod的]
公共无效TestMethod1()
{
  VAR名单=新的名单,其中,计算器>()
  {
    新的计算器(DashboardsComputationMode.PR,Modes.DailyMode)
    新的计算器(DashboardsComputationMode.CurrentValue,Modes.YearlyMode)
    新的计算器(DashboardsComputationMode.PRCorrected,Modes.MonthlyMode)
  };

  VAR项目=新计算器(DashboardsComputationMode.CurrentValue,Modes.YearlyMode);
  Assert.IsTrue(名单[1] .Equals(项目));
  Assert.IsTrue(list.Contains(项目));
}
 

第一个断言正常工作

  Assert.IsTrue(名单[1] .Equals(项目))
 
想申请CS专业 PayScale高薪牛校全方位解读

但第二次没有

  Assert.IsTrue(list.Contains(项目));
 

解决方案

名单,其中; T&GT;。载 通过使用默认的相等比较器(由EqualityComparer<T>.Default).

下面是关于如何EqualityComparer<T>.Default作品:

  

默认的属性检查类型T是否实现    System.IEquatable 的接口,如果是这样,则返回一个    EqualityComparer 使用该实现。否则,它   返回使用的覆盖的 EqualityComparer   的Object.Equals 和的 Object.GetHash code。通过T提​​供的。

换句话说,你的计算器类要么实现的 System.IEquatable (!不可以的 System.IEqualityComparer )接口或重写的Object.GetHash$c$c 方法。

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));

解决方案

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.