通用 属性 上的浮点数比较
Floating point comparison on generic property
我有一个具有某些属性的通用 class:
class MyClass<TValueType>
where TValueType : struct, IComparable
{
public TValueType Target
{
get { return _target; }
set
{
if (Equals(_target, value)) return;
_target = value;
RaiseTargetChanged(value);
}
}
// Other stuff ...
}
如您所见,我与 object.Equals
进行比较以避免过多的事件调用。但是,如果 TValueType
是双精度、浮点数或小数,我想使用浮点比较扩展方法:
public static bool AlmostEqual(this double x, double y, double delta = 0.00001d)
public static bool AlmostEqual(this float x, float y, float delta = 0.00001f)
public static bool AlmostEqual(this decimal x, decimal y, decimal delta = 0.00001m)
我应该键入比较并强制转换 TValueType 并进行适当的浮点比较,还是有更聪明的方法?
编辑:David Heffernan 的解决方案:
我已经强制将比较器传递给 class:
class MyClass<TValueType>
{
public MyClass(IComparer<TValueType> comparer) { ... }
}
然后我传递一个自定义比较器:
public class FloatingPointComparer : IComparer<double>, IComparer<float>, IComparer<decimal>, IComparer
{
public int Compare(double x, double y)
{
return FloatingComparisonExtensions.CompareTo(x, y);
}
// Rest of Compares are the same
}
我使用 IComparer
而不是 IEqualityComparer
,因为我需要根据最大值和最小值验证目标。
与其在感觉有些脏的通用 class 中使用类型检查代码,不如要求消费者提供 IEqualityComparer<TValueType>
接口来执行比较。如果消费者不提供,则代码将默认为 Object.Equals
.
我有一个具有某些属性的通用 class:
class MyClass<TValueType>
where TValueType : struct, IComparable
{
public TValueType Target
{
get { return _target; }
set
{
if (Equals(_target, value)) return;
_target = value;
RaiseTargetChanged(value);
}
}
// Other stuff ...
}
如您所见,我与 object.Equals
进行比较以避免过多的事件调用。但是,如果 TValueType
是双精度、浮点数或小数,我想使用浮点比较扩展方法:
public static bool AlmostEqual(this double x, double y, double delta = 0.00001d)
public static bool AlmostEqual(this float x, float y, float delta = 0.00001f)
public static bool AlmostEqual(this decimal x, decimal y, decimal delta = 0.00001m)
我应该键入比较并强制转换 TValueType 并进行适当的浮点比较,还是有更聪明的方法?
编辑:David Heffernan 的解决方案:
我已经强制将比较器传递给 class:
class MyClass<TValueType>
{
public MyClass(IComparer<TValueType> comparer) { ... }
}
然后我传递一个自定义比较器:
public class FloatingPointComparer : IComparer<double>, IComparer<float>, IComparer<decimal>, IComparer
{
public int Compare(double x, double y)
{
return FloatingComparisonExtensions.CompareTo(x, y);
}
// Rest of Compares are the same
}
我使用 IComparer
而不是 IEqualityComparer
,因为我需要根据最大值和最小值验证目标。
与其在感觉有些脏的通用 class 中使用类型检查代码,不如要求消费者提供 IEqualityComparer<TValueType>
接口来执行比较。如果消费者不提供,则代码将默认为 Object.Equals
.