Безжизненное сравнение строк в С#
Скажем, у меня две строки: a и b. Чтобы сравнить, имеют ли значения a и имеют одинаковые значения, когда случай игнорируется, я всегда использовал:
// (Assume a and b have been verified not to be null)
if (a.ToLower() == b.ToLower())
Однако, используя Reflector, я видел это несколько раз в .NET Framework:
// (arg three is ignoreCase)
if (string.Compare(a, b, true) == 0)
Я тестировал, что быстрее, а ToLower()
бить Compare()
каждый раз с использованием строк, которые я использовал.
Есть ли причина для Compare()
вместо ToLower()
? Что-то о другом CultureInfo
? Я почесываю голову.
Ответы
Ответ 2
Главное, что вас беспокоит, это не производительность, не правильность, и с этого аспекта метод, который вы, вероятно, хотите использовать для нечувствительного к регистру, либо:
string.Compare(a, b, StringComparison.OrdinalIgnoreCase) == 0;
или
a.Equals(b, StringComparison.OrdinalIgnoreCase)
(Первый полезен, если вы знаете, что строки могут быть нулевыми, а последнее проще писать, если вы уже знаете, что хотя бы одна строка не равна нулю. Я никогда не тестировал производительность, но предполагаю, что это будет аналогично.)
Ordinal
или OrdinalIgnoreCase
- это безопасная ставка, если вы не знаете, что хотите использовать другой метод сравнения; чтобы получить информацию, необходимую для принятия решения прочитать эту статью в MSDN.
Ответ 3
При сравнении строк вы должны всегда использовать явный член StringComparison. Строковые функции несколько непоследовательны в том, как они предпочитают сравнивать строки. Единственный способ гарантировать сравнение используется: a) запомнить все из них (это включает в себя как вас, так и всех в вашей команде) или b) использовать явное сравнение для каждой функции.
Гораздо лучше быть явным и не полагаться на отличное знание группы. Ваши товарищи по команде поблагодарят вас за это.
Пример:
if ( StringComparison.OrdinalIgnoreCase.Equals(a,b) )
Использование ToLower для сравнения имеет 2 проблемы, которые я могу придумать с головы.
- Он выделяет память. Функции сравнения не должны выделять память, если они абсолютно не нужны.
- Строки можно опустить несколькими способами. Наиболее заметный Порядковый или Культурный Чувствительный ниже. Каким образом работает .ToLower()? Лично я не знаю. Гораздо лучше передать явную культуру, чем полагаться на дефолт.
Ответ 4
ToLower() не является функцией сравнения, она помещает строку в нижний регистр. Когда оператор == используется для объектов String в С#, он оптимизируется компилятором. В основе оба зависят от System.String.Equals, как показано в Reflector.
Ответ 5
Другая статья MSDN, в которой представлены некоторые ДО и DON'T и рекомендации по использованию метода сравнения в различных случаях: Новые рекомендации по использованию строк в Microsoft.NET 2.0
Ответ 6
Может ли ваш пост ваш тест, который показывает вызов ToLower(), быстрее, чем сравнение без учета регистра? Мои тесты показывают обратное, чтобы быть правдой! Независимо от того, имеются ли другие плакаты о правильности.