C# IEqualityComparer 和 Contains 方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14580595/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
IEqualityComparer and Contains method
提问by Pablo Rodríguez
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
我有一个带有这 2 个枚举字段的简单类,我试图在集合 ( List<T>
) 中找到此对象的一项,但包含方法无法正常工作
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));
采纳答案by Nikolay Khil
List<T>.Contains
determines equality by using the default equality comparer (the one returned by the EqualityComparer<T>.Default
).
List<T>.Contains
使用默认的相等比较器(由 返回的比较器)确定相等EqualityComparer<T>.Default
。
Here's the MSDN explanation on how EqualityComparer<T>.Default
works:
这是关于如何EqualityComparer<T>.Default
工作的 MSDN 解释:
The Default property checks whether type T implements the System.IEquatableinterface and, if so, returns an EqualityComparerthat uses that implementation. Otherwise, it returns an EqualityComparerthat uses the overrides of Object.Equalsand Object.GetHashCodeprovided by T.
Default 属性检查类型 T 是否实现 System.IEquatable接口,如果是,则返回使用该实现的 EqualityComparer。否则,它返回一个EqualityComparer,它使用T 提供的Object.Equals和Object.GetHashCode的覆盖 。
In other words, your Calculator
class should either implement the System.IEquatable(notthe System.IEqualityComparer
!) interface or override the Object.Equalsand Object.GetHashCodemethods.
换句话说,你的Calculator
类要么实现System.IEquatable(没有的System.IEqualityComparer
!)接口或重写的Object.Equals和Object.GetHashCode方法。
回答by D J
You are not using IEqualityComparer<Calculator>
in Equals and Contains both. EqualityComparer
has a different significance. I corrected the code for you.
您没有IEqualityComparer<Calculator>
在 Equals 和 Contains 中使用。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,
}
Now both should return true.
现在两者都应该返回 true。