如何在 C# 中处理接受 IComparable 的通用方法的 double.NaN
Posted
技术标签:
【中文标题】如何在 C# 中处理接受 IComparable 的通用方法的 double.NaN【英文标题】:how to handle double.NaN for Generic method accepting IComparable in C# 【发布时间】:2013-01-04 21:45:02 【问题描述】:我有一个通用的GetMinimum
方法。它接受 IComparable 类型的数组(因此它可能是 string[]
或 double[]
)。在double[]
的情况下,如何实现此方法以忽略double.NaN
值? (我正在寻找好的做法)
当我传递这个数组时
double[] inputArray = double.NaN, double.NegativeInfinity, -2.3, 3 ;
它返回 double.NaN!
public T GetMinimum<T>(T[] array) where T : IComparable<T>
T result = array[0];
foreach (T item in array)
if (result.CompareTo(item) > 0)
result = item;
return result;
【问题讨论】:
【参考方案1】:你不能从方法内部。原因是您不知道方法内部的T
可以是什么。也许你可以通过一些小演员,但理想情况下这应该是你的方法:
public T GetMinimum<T>(T[] array, params T[] ignorables) where T : IComparable<T>
T result = array[0]; //some issue with the logic here.. what if array is empty
foreach (T item in array)
if (ignorables.Contains(item)
continue;
if (result.CompareTo(item) > 0)
result = item;
return result;
现在叫这个:
double[] inputArray = double.NaN, double.NegativeInfinity, -2.3, 3 ;
GetMinimum(inputArray, double.NaN);
如果您确定只有一个项目被忽略,那么您可以只将T
作为第二个参数(也许作为可选参数)。
或者用更短的方法,只是:
inputArray.Where(x => !x.Equals(double.NaN)).Min();
【讨论】:
你确定它不返回 double.NaN 吗? 那行不通——调用ignorables.Contains()
不会成功,因为double.NaN.Equals(double.NaN)
将返回false
。您需要使用double.IsNaN()
处理特殊情况。
@HosseinNarimaniRad 它可能会返回,这就是为什么我说里面的逻辑不是那么合理。但编辑不是我的主要优先事项
@nawfal 嗯,我的立场是正确的。来自 MSDN:“如果通过调用 Equals 方法测试两个 Double.NaN 值是否相等,则该方法返回 true。但是,如果使用相等运算符测试两个 NaN 值是否相等,则该运算符返回 false。”这似乎有点奇怪!【参考方案2】:
根据这个问答,很复杂:Sorting an array of Doubles with NaN in it
幸运的是,您可以绕过它:
if( item is Single || item is Double )
Double fitem = (Double)item;
if( fitem == Double.NaN ) continue;
【讨论】:
这行不通,因为fitem == Double.NaN
将始终评估为假,即使fitem
实际上是Double.NaN
。你必须使用Double.IsNaN(fitem)
(或fitem.Equals(Double.NaN)
,正如我发现的那样)。【参考方案3】:
由于NaN < x
和NaN > x
都将始终为false,因此根本没有定义可以 包含NaN
的集合的最小值。这就像除以零:没有有效的答案。
因此,合乎逻辑的方法是预先过滤这些值。这不会是通用的,但应该没问题。
var results = inputArray.EliminateNaN().GetMinimum();
关注点分离:过滤不应该是GetMinimum()
的责任(和负担)。
【讨论】:
是的。完全一样inputArray.Where(x => !x.Equals(double.NaN)).Min();
以上是关于如何在 C# 中处理接受 IComparable 的通用方法的 double.NaN的主要内容,如果未能解决你的问题,请参考以下文章