![](/img/trans.png)
[英]How can I write my IEqualityComparer without checking for nulls?
[英]How to handle nulls in IEqualityComparer?
以下方法來自 XUnit Assert class:
public static void Equal<T>(IEnumerable<T> expected, IEnumerable<T> actual, IEqualityComparer<T> comparer);
我將其用作:
IEnumerable<Decimal?> x = getXValues();
IEnumerable<Decimal?> y = getYValues();
Assert.Equal(x, y, new DecimalToleranceEqualityComparer(0.01m));
我正在使用IEqualityComparer
,因為可以考慮 2.526 等於 2.524。
我收到一個錯誤,因為DecimalToleranceEqualityComparer
僅適用於Decimal
...
x
和y
可能具有null
值。 DecimalToleranceEqualityComparer
是:
public class DecimalToleranceEqualityComparer : IEqualityComparer<Decimal> {
private readonly Decimal _tolerance;
public DecimalToleranceEqualityComparer(Decimal tolerance) {
_tolerance = tolerance;
}
public Boolean Equals(Decimal x, Decimal y) {
return Math.Abs(x - y) <= _tolerance;
}
public Int32 GetHashCode(Decimal obj) {
return obj.GetHashCode();
}
}
我想如果2個值是空值,它們應該被認為是相等的......
如何更改IEqualityComparer
以使其處理空值?
這段代碼對我有用。 真正的訣竅在於Equals
方法的實現。 還要記住GetHashCode
中的 null 檢查。
static void Main(string[] args)
{
IEnumerable<Decimal?> x = new List<Decimal?> { 1.51m, 3, null };
IEnumerable<Decimal?> y = new List<Decimal?> { 1.6m, 3, null };
Assert.Equal(x, y, new DecimalToleranceEqualityComparer(0.1m));
}
public class DecimalToleranceEqualityComparer : IEqualityComparer<Decimal?>
{
private readonly Decimal _tolerance;
public DecimalToleranceEqualityComparer(Decimal tolerance)
{
_tolerance = tolerance;
}
public Boolean Equals(Decimal? x, Decimal? y)
{
if (!x.HasValue && !y.HasValue)
{
// Both null -> they are equal
return true;
}
else if (!x.HasValue || !y.HasValue)
{
// One is null, other is not null -> not equal
return false;
}
else
{
// both have values -> run the actual comparison
return Math.Abs(x.Value - y.Value) <= _tolerance;
}
}
public Int32 GetHashCode(Decimal? obj)
{
if (obj.HasValue)
{
return obj.GetHashCode();
}
else
{
// Here decide what you need
return string.Empty.GetHashCode();
}
}
}
想到的一個選項可能是為可為空的十進制類型IEqualityComparer<decimal?>
實現新的相等比較器,它可以在內部使用您現有的DecimalToleranceEqualityComparer
。 就像是
public Boolean Equals(Decimal? x, Decimal? y) {
return (x.HasValue && y.HasValue)?
_decimalToleranceEqualityComparer.Equals(x.Value,y.Value)
: x == y;
}
您正在提供一個Nullable<decimal>
的列表,而您的IEqualityComparer
需要一個Decimal
的列表。
像這樣重寫你應該沒問題:
public class DecimalToleranceEqualityComparer : IEqualityComparer<decimal?>
{
private readonly decimal _tolerance;
public DecimalToleranceEqualityComparer(decimal tolerance)
{
_tolerance = tolerance;
}
public bool Equals(decimal? x, decimal? y)
{
if (!x.HasValue && !y.HasValue) return true;
if (!x.HasValue || !y.HasValue) return false;
return Math.Abs(x.Value - y.Value) <= _tolerance;
}
public int GetHashCode(decimal? obj)
{
return obj.GetHashCode();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.