Ошибка сортировки .NET IComparer

Недавно я столкнулся с очень странной проблемой. Я развернул новую версию программы и получаю эту ошибку при внутреннем вызове метода IComparer.Compare():

Unable to sort because the IComparer.Compare0 method returns inconsistent
results. Either a value does not compare equal to itself, or one value     repeatedly
compared to another value yields different results. x:",x's type: 'String',
IComparer.".

Странно то, что я не могу воспроизвести эту проблему на своем компьютере. У меня этого не происходит в Visual Studio 2013 (отладочная или выпускная версии), а также при установке приложения. Что еще более странно, это даже не происходит на каждом компьютере в производстве, только около 30% из них.

Мое приложение нацелено на .NET Framework 4, а целевой платформой является x86.

В моем коде есть только один экземпляр объекта IComparer, вот он:

public int Compare(string stringOne, string stringTwo)
{
    if (stringOne == stringTwo) { return 0; }
    else if (stringOne == null) { return stringTwo == null ? 0 : -1; }
    else if (stringTwo == null) { return stringOne == null ? 0 : 1; }

    else if (stringOne.StartsWith("_") && !stringTwo.StartsWith("_"))
    {
        return -1;
    }
    else if (!stringOne.StartsWith("_") && stringTwo.StartsWith("_"))
    {
        return 1;
    }
    else if ((stringOne.StartsWith("l") || stringOne.StartsWith("L")) &&
            (!stringTwo.StartsWith("l") || !stringTwo.StartsWith("L")))
    {
        return -1;
    }
    else if ((!stringOne.StartsWith("l") || !stringOne.StartsWith("L")) &&
              (stringTwo.StartsWith("l") || stringTwo.StartsWith("L")))
    {
        return 1;
    }
    else
    {
        if (stringTwo == null) { return 1; }
        else { return stringOne.CompareTo(stringTwo) == 1 ? -1 : 1; }
    }
}

Кто-нибудь еще имел эту проблему и нашел ее решение? Похоже, мой компаратор охватывает все случаи? Я полностью потерял эту проблему и понятия не имею, что делать дальше. Любая помощь будет оценена.


person kformeck    schedule 15.09.2015    source источник
comment
Вы можете ввести трассировку, чтобы увидеть, каковы значения? что провал?   -  person Daniel A. White    schedule 15.09.2015
comment
вероятный дубликат: stackoverflow.com/questions/13407412/   -  person Daniel A. White    schedule 15.09.2015
comment
Это напрямую не помогает вашему вопросу, но взгляните на String.StartsWith(String, StringComparison). Тогда вам не нужно проверять, скажем, и l, и L.   -  person Wai Ha Lee    schedule 15.09.2015


Ответы (1)


Этот

else if ((stringOne.StartsWith("l") || stringOne.StartsWith("L")) &&
            (!stringTwo.StartsWith("l") || !stringTwo.StartsWith("L")))
    {
        return -1;
    }
    else if ((!stringOne.StartsWith("l") || !stringOne.StartsWith("L")) &&
              (stringTwo.StartsWith("l") || stringTwo.StartsWith("L")))
    {
        return 1;
    }

должно быть

else if ((stringOne.StartsWith("l") || stringOne.StartsWith("L")) &&
            !(stringTwo.StartsWith("l") || stringTwo.StartsWith("L")))
    {
        return -1;
    }
    else if (!(stringOne.StartsWith("l") || stringOne.StartsWith("L")) &&
              (stringTwo.StartsWith("l") || stringTwo.StartsWith("L")))
    {
        return 1;
    }

В качестве примечания: то, как вы написали эту функцию сравнения, крайне неэффективно.

person Ivan Stoev    schedule 15.09.2015
comment
Спасибо! Я закончил тем, что понял это самостоятельно, и так получилось, что именно так я это и исправил. - person kformeck; 15.09.2015