Есть ли в C # нечувствительный к регистру оператор равенства? - PullRequest
146 голосов
/ 10 марта 2009

Я знаю, что учитывается регистр:

if (StringA == StringB) {

Так есть ли оператор, который будет сравнивать две строки нечувствительным образом?

Ответы [ 13 ]

273 голосов
/ 10 марта 2009

Попробуйте это:

string.Equals(a, b, StringComparison.CurrentCultureIgnoreCase);
28 голосов
/ 10 сентября 2012

Лучший способ сравнить 2 строки, игнорируя регистр букв, - это использовать статический метод String.Equals , задающий порядковое игнорирование сравнения строк регистра. Это также самый быстрый способ, гораздо быстрее, чем преобразование строк в нижний или верхний регистр и сравнение их после этого.

Я проверил производительность обоих подходов, и сравнение строк в регистре игнорирования было более чем в 9 раз быстрее ! Это также более надежно, чем преобразование строк в нижний или верхний регистр (см. Проблему Turkish i). Поэтому всегда используйте метод String.Equals для сравнения строк на равенство:

String.Equals(string1, string2, StringComparison.OrdinalIgnoreCase);

Если вы хотите выполнить сравнение строк для конкретной культуры, вы можете использовать следующий код:

String.Equals(string1, string2, StringComparison.CurrentCultureIgnoreCase);

Обратите внимание, что во втором примере используется логика сравнения строк текущей культуры, что делает его более медленным, чем сравнение "порядкового игнорирования регистра" в первом примере, поэтому, если вам не нужна логика сравнения строк для конкретной культуры и вы после максимальной производительности, используйте сравнение «порядковый регистр игнорирования».

Для получения дополнительной информации, прочитайте полную историю в моем блоге .

18 голосов
/ 10 марта 2009

В статическом классе StringComparer есть ряд свойств, которые возвращают компараторы для любого типа чувствительности к регистру:

StringComparer Свойства

Например, вы можете позвонить

StringComparer.CurrentCultureIgnoreCase.Equals(string1, string2)

или

StringComparer.CurrentCultureIgnoreCase.Compare(string1, string2)

Это немного чище, чем перегрузки string.Equals или string.Compare, которые принимают аргумент StringComparison.

15 голосов
/ 10 марта 2009
System.Collections.CaseInsensitiveComparer

или

System.StringComparer.OrdinalIgnoreCase
9 голосов
/ 10 марта 2009
string.Equals(StringA, StringB, StringComparison.CurrentCultureIgnoreCase);
7 голосов
/ 10 марта 2009

или

if (StringA.Equals(StringB, StringComparison.CurrentCultureIgnoreCase)) {

но вы должны быть уверены, что StringA не равен нулю. Так что, вероятно, лучше использовать:

string.Equals(StringA , StringB, StringComparison.CurrentCultureIgnoreCase);

как предложил Джон

РЕДАКТИРОВАТЬ: исправлена ​​ошибка

4 голосов
/ 09 мая 2018

Вот идея упростить синтаксис:

public class IgnoreCase
{
    private readonly string _value;

    public IgnoreCase(string s)
    {
        _value = s;
    }

    protected bool Equals(IgnoreCase other)
    {
        return this == other;
    }

    public override bool Equals(object obj)
    {
        return obj != null &&
               (ReferenceEquals(this, obj) || (obj.GetType() == GetType() && this == (IgnoreCase) obj));
    }

    public override int GetHashCode()
    {
        return _value?.GetHashCode() ?? 0;
    }

    public static bool operator ==(IgnoreCase a, IgnoreCase b)
    {
        return string.Equals(a, b, StringComparison.OrdinalIgnoreCase);
    }

    public static bool operator !=(IgnoreCase a, IgnoreCase b)
    {
        return !(a == b);
    }

    public static implicit operator string(IgnoreCase s)
    {
        return s._value;
    }

    public static implicit operator IgnoreCase(string s)
    {
        return new IgnoreCase(s);
    }
}

Можно использовать как:

Console.WriteLine((IgnoreCase) "a" == "b"); // false
Console.WriteLine((IgnoreCase) "abc" == "abC"); // true
Console.WriteLine((IgnoreCase) "Abc" == "aBc"); // true
Console.WriteLine((IgnoreCase) "ABC" == "ABC"); // true
4 голосов
/ 10 марта 2009

Вы можете использовать

if (stringA.equals(StringB, StringComparison.CurrentCultureIgnoreCase))
3 голосов
/ 10 марта 2009

Оператор? НЕТ, но я думаю, что вы можете изменить свою культуру, чтобы сравнение строк не учитывало регистр.

// you'll want to change this...
System.Threading.Thread.CurrentThread.CurrentCulture
// and you'll want to custimize this
System.Globalization.CultureInfo.CompareInfo

Я уверен, что это изменит способ сравнения строк оператором equals.

2 голосов
/ 24 июля 2012

Я так привык печатать в конце этих методов сравнения: , StringComparison.

Итак, я сделал расширение.

namespace System
{   public static class StringExtension
    {
        public static bool Equals(this string thisString, string compareString,
             StringComparison stringComparison)
        {
            return string.Equals(thisString, compareString, stringComparison);
        }
    }
}

Просто обратите внимание, что вам нужно проверить нулевое значение на thisString до вызова ext.

...