C# 国际比较问题

C# 国际比较问题,c#,.net,icomparer,r-tree,C#,.net,Icomparer,R Tree,我有一个奇怪的问题,我不知道原因。我会尽量把我的问题说清楚 我有一个RTree类,在这个类中,我想比较两个矩形(这里我称为envelope,它包含minX,minY,maxX,maxY),所以我们有一个比较器类,如下所示: private class AnonymousXComparerImpl : IComparer { public AnonymousXComparerImpl() { } public int Compare(object o1, object o

我有一个奇怪的问题,我不知道原因。我会尽量把我的问题说清楚

我有一个RTree类,在这个类中,我想比较两个矩形(这里我称为envelope,它包含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;
    }
}
这是奇怪的部分。此错误仅发生在未安装VistualStudio的.net 4.0中。如果机器安装了VS或.net 4.5,则无法再次出现此问题。

在这种情况下,我无法理解为什么会发生这种情况。如果您有调试此类问题的经验,我将不胜感激

谢谢,
Howard

如果例如
ea.MinX
NaN
a
将是
NaN
,并且
a>b
a
都将是
false
。这意味着,有些对象的比较结果与其他对象相同

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

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

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

正如@Seph和@Jeppe在注释中所指出的,这是正确的,因此最后一行可以替换为
返回a.CompareTo(b)

一个可能的原因是您的信息在比较过程中实际发生了更改

如果您在后台线程中进行排序,那么在两次请求相同项目时,如果比较得到不同的值,则肯定会出现此错误

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

确保缓存比较的值,以便始终返回一致的结果。或者接受错误可能不时发生的事实,如果发生了,则重新进行排序


这也解释了您对机器/操作系统依赖性的感觉。根据软件和硬件的不同,多线程问题会出现不同的情况。

这里我能想到的唯一一件事是浮点问题,这意味着相等性与相同的项不完全匹配,不知道为什么它特定于v4。您是否尝试强制执行舍入级别?尝试使用
decimal
数据类型而不是double。没有其他线程参与吗?此外,这个线程可能很有趣:MinX、MaxX值是否可以是NaN?您是否尝试过使用
返回a.CompareTo(b)而不是?你的问题可能是NaN!=NaN.+1这听起来似乎有道理——尽管我不知道为什么.Net版本的结果会有所不同。但是,如果数据中可能有NAN(OP说可以),那么它肯定会导致所观察到的问题。这是有道理的,请允许我暂时保留此线程,稍后标记为答案。非常感谢。@MatthewWatson-也许新版本中的
Sort
函数没有进行不必要的比较,因此无法检测不一致。只将原始代码(问题)中的最后一行替换为:
返回a.CompareTo(b)。方法
double.CompareTo(double)
处理
NaN
和无穷大。但是,它不会投影到
0.0
NaN
将位于任何负数之前。补充:刚才看到Seph很久以前在对问题的评论中提出了这一点。
if (double.IsNaN(a)) a = 0.0;
if (double.IsNaN(b)) b = 0.0;