5

我有一个奇怪的问题,我没有线索来追踪原因。我会尽量清楚地描述我的问题。

我有一个 RTree 类,在这个类中,我想比较两个矩形(这里我称为信封,它包含 minX、minY、maxX、maxY),所以我们有一个比较器类如下:

private class AnonymousXComparerImpl : IComparer
{
    public AnonymousXComparerImpl()
    { }

    public int Compare(object o1, object o2) 
    {
        IEnvelope ea = (IEnvelope)((IBoundable)o1).Bounds;
        IEnvelope eb = (IEnvelope)((IBoundable)o2).Bounds;
        double a = (ea.MinX + ea.MaxX) / 2d;
        double b = (eb.MinX + eb.MaxX) / 2d;
        return a > b ? 1 : a < b ? -1 : 0;
    }
}

使用这个比较器,我们可以维护一个信封的 ArrayList 并轻松对其进行排序,信封是随机添加的。当我们调用以下代码时,我们遇到了

无法排序,因为 IComparer.Compare() 方法返回不一致的结果。一个值与自身比较不相等,或者一个值与另一个值重复比较会产生不同的结果。

sortedChildBoundables.Sort(new AnonymousXComparerImpl());

这是奇怪的部分。此错误仅发生在未安装 VisualStudio 的 .net 4.0 中。如果机器安装了 VS 或 .net 4.5,则此问题无法再次出现。

在这种情况下,我无法弄清楚它为什么会发生。如果您对调试此类问题有任何经验,那就太好了,我很感激。

谢谢,霍华德

4

2 回答 2

5

如果例如ea.MinXis NaNawill beNaN和 botha > ba < bwill be false。这意味着,有些对象比较等于所有其他对象。

您首先必须决定如何对包含NaN的对象进行排序。

一个简单的解决方法可能是插入

if (double.IsNaN(a)) a = 0.0;
if (double.IsNaN(b)) b = 0.0;

正如@Seph 和@Jeppe 在评论中指出的那样,double.CompareTo做正确的事,所以最后一行可以替换为return a.CompareTo(b);.

于 2013-05-08T08:47:56.830 回答
0

一个可能的原因是您的信息在比较过程中实际上发生了变化。

如果您在后台线程中进行排序,如果在两次询问时比较获得相同项目的不同值,您肯定会收到此错误。

例如,如果您的主线程在比较运行时更新了其中一个值(可能通过数据绑定)。

确保缓存比较的值,以便始终返回一致的结果。或者接受错误可能会不时发生,如果确实如此,请重做排序。

这也将解释您对机器/操作系统依赖的感觉。多线程问题的发生因软件和硬件的不同而不同。

于 2016-01-21T08:27:03.593 回答