С# string.IndexOf() возвращает неожиданное значение
Этот вопрос относится к устройствам С#,.net Compact Framework 2 и Windows CE 5.
Я столкнулся с ошибкой в DLL.net, которая использовалась на самых разных устройствах CE в течение многих лет, без каких-либо проблем. Внезапно на новом устройстве Windows CE 5.0 эта ошибка появилась в следующем коде:
string s = "Print revenue receipt"; // has only single space chars
int i = s.IndexOf(" "); // two space chars
Я ожидаю, что я будет -1, однако это было верно только до сегодняшнего дня, когда indexOf неожиданно вернул 5.
Поскольку это поведение не возникает при использовании
int i = s.IndexOf(" ", StringComparison.Ordinal);
я вполне уверен, что это феномен феномена, основанного на культуре, но я не могу распознать разницу, которое делает это новое устройство. Это в основном идентичная версия известного устройства (просто быстрый процессор и новая плата).
Оба устройства:
- запустить Windows CE 5.0 с идентичной локализацией
- Отчеты System.Environment.Version 2.0.0045.0
- CultureInfo.CurrentUICulture и CultureInfo.CurrentCulture report 'en-GB' (также тестируется с де-DE)
- "все" связанные ключи реестра равны.
Новое устройство имело предустановленную CF 3.5, чьи файлы GAC, которые я экспериментально переименовал, без изменений описанного поведения. Поскольку во время выполнения всегда сообщается версия 2.0.7045.0, я предполагаю, что эти сборки не имеют никакого эффекта.
Хотя это не сложно исправить, я не могу этого вынести, когда что-то кажется волшебным. Любые намеки на то, что мне не хватает?
Изменить: он становится незнакомцем и незнакомцем, см. снимок экрана:
![screenshot]()
Еще одно:
![screenshot]()
Ответы
Ответ 1
Я считаю, что у вас уже есть ответ, используя порядковый поиск
int i = s.IndexOf(" ", StringComparison.Ordinal);
Вы можете прочитать небольшой раздел в документации для String Class, который должен сказать это по этому вопросу:
Строковые методы поиска, такие как String.StartsWith и String.IndexOf, также могут выполнять культурно-чувствительные или упорядоченные сравнения строк. Следующий пример иллюстрирует различия между порядковыми и культурно-чувствительными сравнениями с использованием метода IndexOf. Культурно-чувствительный поиск, в котором текущая культура является английским (Соединенные Штаты), считает подстроку "oe" соответствующей лигатуре "œ". Поскольку мягкий дефис (U + 00AD) является символом нулевой ширины, поиск рассматривает мягкий дефис как эквивалент Empty и находит совпадение в начале строки. С другой стороны, порядковый поиск не находит соответствия в любом случае.
Ответ 2
Культурные вещи действительно могут казаться довольно волшебными в некоторых системах. То, что я всегда делал после многих лет боли, всегда задает информацию о культуре вручную InvariantCulture
, где я не хочу явно различать поведение для разных культур. Поэтому мое предложение было бы: сделать, чтобы проверка IndexOf
всегда использовала одну и ту же информацию о культуре, например:
int i = s.IndexOf(" ", StringComparison.InvariantCulture);
Ответ 3
Ссылка на http://msdn.microsoft.com/en-us/library/k8b1470s.aspx гласит:
"Символьные наборы включают в себя неосведомленные символы, которые являются символами, которые не учитываются при выполнении лингвистического или культурно-чувствительного сравнения. В чувствительном к культуре поиске, если значение содержит незнатный символ, результат эквивалентен поиску с этим символом удален".
Это из 4.5 ссылок, ссылки из предыдущих версий не содержат ничего подобного.
Итак, позвольте мне угадать: они изменили правила с 4,0 до 4,5, и теперь второе пространство из двух пространственных последовательностей считается "неосведомленным персонажем" - по крайней мере, если движок распознает вашу строку как текст на английском языке (например, в строке примера s), в противном случае нет.
И как-то на вашем новом устройстве вместо dll ожидаемой версии 2.0 используется dll.
Дикая догадка, я знаю:)