关于.NET:是否有不区分大小写的等号运算符?

Is there a C# case insensitive equals operator?

我知道以下内容区分大小写:

1
if (StringA == StringB) {

那么有没有一个运算符可以不敏感地比较两个字符串?


试试这个:

1
string.Equals(a, b, StringComparison.CurrentCultureIgnoreCase);


比较两个忽略字母大小写的字符串的最佳方法是使用string.equals静态方法,指定顺序忽略大小写字符串比较。这也是最快的方法,比将字符串转换为小写或大写并在转换后进行比较快得多。

我测试了这两种方法的性能,并且顺序忽略大小写字符串的比较速度快了9倍以上!它也比将字符串转换为小写或大写更可靠(请看土耳其语i问题)。因此,始终使用string.equals方法比较字符串是否相等:

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

如果要执行区域性特定的字符串比较,可以使用以下代码:

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

请注意,第二个示例使用当前区域性的字符串比较逻辑,这使得它比第一个示例中的"序数忽略大小写"比较慢,因此,如果您不需要任何特定于区域性的字符串比较逻辑,并且您追求最大性能,请使用"序数忽略大小写"比较。

有关详细信息,请阅读我博客上的完整文章。


StringComparer静态类上有许多属性,可以返回任何类型的区分大小写的比较器:

StringComparer属性

例如,您可以调用

1
StringComparer.CurrentCultureIgnoreCase.Equals(string1, string2)

1
StringComparer.CurrentCultureIgnoreCase.Compare(string1, string2)

它比采用StringComparison参数的string.Equalsstring.Compare重载更干净。


1
System.Collections.CaseInsensitiveComparer

1
System.StringComparer.OrdinalIgnoreCase


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

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

但您需要确保stringa不是空的。所以最好使用:

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

正如约翰所建议的

编辑:更正错误


这里有一个简化语法的想法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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);
    }
}

可用的类似:

1
2
3
4
Console.WriteLine((IgnoreCase)"a" =="b"); // false
Console.WriteLine((IgnoreCase)"abc" =="abC"); // true
Console.WriteLine((IgnoreCase)"Abc" =="aBc"); // true
Console.WriteLine((IgnoreCase)"ABC" =="ABC"); // true


你可以使用

1
if (stringA.equals(StringB, StringComparison.CurrentCultureIgnoreCase))

操作员?不,但是我认为你可以改变你的文化,这样字符串比较就不区分大小写了。

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

我相信它会改变用equals运算符比较字符串的方式。


我习惯于在这些比较方法的末尾键入:, StringComparison.

所以我做了一个扩展。

1
2
3
4
5
6
7
8
9
10
namespace System
{   public static class StringExtension
    {
        public static bool Equals(this string thisString, string compareString,
             StringComparison stringComparison)
        {
            return string.Equals(thisString, compareString, stringComparison);
        }
    }
}

请注意,在调用ext之前,您需要检查thisString上的空值。


其他答案在这里是完全有效的,但不知何故,输入StringComparison.OrdinalIgnoreCase和使用string.Compare需要一些时间。

我已经编写了简单的字符串扩展方法,您可以在其中指定比较是区分大小写的还是不区分大小写的布尔值-请参见以下答案:

https://stackoverflow.com/a/49208128/2338477


1
string.Compare(string1, string2, true)


1
if (StringA.ToUpperInvariant() == StringB.ToUpperInvariant()) {

人们报告ToUpperInvariant()比ToLowerInvariant()更快。