C#中字符串比较方法的差异

时间:2008-09-04 17:44:10

标签: c# string comparison

比较C#中的字符串非常简单。事实上,有几种方法可以做到这一点。我在下面的块中列出了一些。我感到好奇的是它们之间的区别以及何时应该使用其他区别?是否应该不惜一切代价避免?还有更多我没有列出?

string testString = "Test";
string anotherString = "Another";

if (testString.CompareTo(anotherString) == 0) {}
if (testString.Equals(anotherString)) {}
if (testString == anotherString) {}

(注意:我在这个例子中寻找平等,不小于或大于,但也可以随意发表评论)

11 个答案:

答案 0 :(得分:219)

以下是这些功能如何运作的规则:

<强> stringValue.CompareTo(otherStringValue)

  1. null出现在字符串
  2. 之前
  3. 它使用CultureInfo.CurrentCulture.CompareInfo.Compare,这意味着它将使用依赖于文化的比较。这可能意味着ß将与德国的SS或类似的
  4. 进行比较

    <强> stringValue.Equals(otherStringValue)

    1. null不等同于任何事情
    2. 除非您指定StringComparison选项,否则它将使用看起来像直接序数相等检查的内容,即ßSS在任何语言或文化中都不相同
    3. <强> stringValue == otherStringValue

      1. stringValue.Equals()不同。
      2. ==运算符调用静态Equals(string a, string b)方法(后者又转到内部EqualsHelper进行比较。
      3. .Equals()字符串上调用null会导致null引用异常,而在==上则不会。
      4. <强> Object.ReferenceEquals(stringValue, otherStringValue)

        只检查引用是否相同,即它不只是具有相同内容的两个字符串,而是将字符串对象与自身进行比较。


        请注意,使用上面使用方法调用的选项时,会有多个选项来指定如何进行比较。

        我的建议是,如果您只是想检查是否平等,那就是决定是否要使用与文化相关的比较,然后使用.CompareTo.Equals,具体取决于选择。

答案 1 :(得分:70)

来自MSDN:

  

“CompareTo方法主要用于排序或   按字母顺序排列的操作。主要时不应该使用它   方法调用的目的是确定是否有两个字符串   当量。要确定两个字符串是否相同,请调用   等于方法。“

他们建议在仅仅考虑平等时使用.Equals而不是.CompareTo。我不确定.Equals==string之间是否存在差异。我有时会为自己的班级使用.EqualsObject.ReferenceEquals代替==,以防有人稍后出现并重新定义该班级的==运算符。

答案 2 :(得分:50)

如果您对BCL方法的差异感到好奇,Reflector是您的朋友: - )

我遵循以下准则:

完全匹配: 编辑:我之前总是使用==运算符,其原理是在Equals(string,string)内对象==运算符用于比较对象引用但它似乎strA.Equals(strB)总体上比string.Equals(strA,strB),strA == strB和string.CompareOrdinal(strA,strB)快1-11%。我在Interned / non-interned字符串值上使用StopWatch进行循环测试,具有相同/不同的字符串长度和不同的大小(1B到5MB)。

strA.Equals(strB)

人类可读的匹配(西方文化,不区分大小写):

string.Compare(strA, strB, StringComparison.OrdinalIgnoreCase) == 0

人类可读的匹配(所有其他文化,由CultureInfo定义的不敏感的案例/重音/假名/等):

string.Compare(strA, strB, myCultureInfo) == 0

人工可读的自定义规则(所有其他文化):

CompareOptions compareOptions = CompareOptions.IgnoreCase
                              | CompareOptions.IgnoreWidth
                              | CompareOptions.IgnoreNonSpace;
string.Compare(strA, strB, CultureInfo.CurrentCulture, compareOptions) == 0

答案 3 :(得分:18)

正如Ed所说,CompareTo用于排序。

然而,.Equals和==之间存在差异。

==解析为基本上以下代码:

if(object.ReferenceEquals(left, null) && 
   object.ReferenceEquals(right, null))
    return true;
if(object.ReferenceEquals(left, null))
    return right.Equals(left);
return left.Equals(right);

简单的原因是以下内容会引发异常:

string a = null;
string b = "foo";

bool equal = a.Equals(b);

以下不会:

string a = null;
string b = "foo";

bool equal = a == b;

答案 4 :(得分:15)

有关字符串比较问题的详细解释和做法可以在文章New Recommendations for Using Strings in Microsoft .NET 2.0Best Practices for Using Strings in the .NET Framework中找到。


每个提到的方法(和其他)都有特殊目的。它们之间的关键区别在于它们默认使用的是StringComparison Enumeration。有几种选择:

  • 的CurrentCulture
  • CurrentCultureIgnoreCase
  • InvariantCulture的
  • InvariantCultureIgnoreCase
  • OrdinalIgnoreCase

以上每种比较类型都针对不同的用例:

    • 区分大小写的内部标识符
    • XML和HTTP等标准中的区分大小写的标识符
    • 区分大小写的安全相关设置
  • OrdinalIgnoreCase
    • 不区分大小写的内部标识符
    • XML和HTTP等标准中的不区分大小写的标识符
    • 文件路径(在Microsoft Windows上)
    • 注册表项/值
    • 环境变量
    • 资源标识符(例如句柄名称)
    • 不区分大小写的安全相关设置
  • InvariantCulture或InvariantCultureIgnoreCase
    • 一些持久的语言相关数据
    • 显示需要固定排序顺序的语言数据
  • CurrentCulture或CurrentCultureIgnoreCase
    • 向用户显示的数据
    • 大多数用户输入

请注意,自.NET 2.0以来,存在StringComparison Enumeration以及字符串比较方法的重载。


String.CompareTo Method (String)

实际上是IComparable.CompareTo Method的类型安全实现。默认解释:CurrentCulture。

用法:

  

CompareTo方法主要用于排序或按字母顺序排列操作

因此

  

实现IComparable接口必然会使用此方法

String.Compare Method

String Class的静态成员,它有许多重载。默认解释:CurrentCulture。

  

只要有可能,您应该调用包含StringComparison参数的Compare方法的重载。

String.Equals Method

从Object类重写并为类型安全重载。默认解释:序数。 请注意:

  

String类的相等方法包括静态等于静态运算符== 实例方法等于


StringComparer class

还有另一种处理字符串比较的方法,特别是要排序:

  

您可以使用StringComparer class创建特定于类型的比较,以对通用集合中的元素进行排序。 Hashtable,Dictionary,SortedList和SortedList等类使用StringComparer类进行排序。

答案 5 :(得分:7)

并非性能通常在99%的时间内都很重要,但是如果你必须在一个循环中这样做几百万次,我强烈建议你使用.Equals或==因为它一旦它发现一个与它不匹配的字符会将整个事情抛出为假,但是如果你使用CompareTo,它必须弄清楚哪个字符小于另一个字符,导致性能时间稍差。

如果您的应用将在不同的国家/地区运行,我建议您查看CultureInfo含义,并可能使用.Equals。由于我只为美国编写应用程序(并不关心某人是否无法正常使用),我总是只使用==。

答案 6 :(得分:5)

在此处列出的表单中,两者之间没有太大区别。 CompareTo最终调用CompareInfo方法,使用当前文化进行比较; Equals运营商会调用==

如果你考虑过载,那么情况会有所不同。 Compare==只能使用当前文化来比较字符串。 EqualsString.Compare可以使用StringComparison枚举参数,您可以指定区分大小写或不区分大小写的比较。只有String.Compare允许您指定CultureInfo并使用默认文化以外的文化进行比较。

由于它的多功能性,我发现我使用String.Compare比任何其他比较方法更多;它让我准确指出我想要的东西。

答案 7 :(得分:2)

要注意的一个重要区别是.Equals()如果第一个字符串为null则抛出异常,而= =不会。

       string s = null;
        string a = "a";
        //Throws {"Object reference not set to an instance of an object."}
        if (s.Equals(a))
            Console.WriteLine("s is equal to a");
        //no Exception
        if(s==a)
            Console.WriteLine("s is equal to a");

答案 8 :(得分:0)

  • s1.CompareTo(s2):如果主要用途是确定两个字符串是否相同,请不要使用
  • s1 == s2:无法忽略大小写
  • s1.Equals(s2,StringComparison):如果s1为null,则抛出NullReferenceException
  • String.Equals(s2,StringComparison):通过淘汰过程,此静态方法是 WINNER (假设一个典型的用例确定两个字符串是否相同)!

答案 9 :(得分:-1)

使用.Equals也更容易阅读

答案 10 :(得分:-9)

使用.Equals,您还可以获得StringComparison选项。忽略案件和其他事情非常方便。

顺便说一句,这将评估为假

string a = "myString";
string b = "myString";

return a==b

由于==比较a和b(它们是指针)的值,如果指针指向内存中的同一个对象,这将仅计算为true。 .Equals取消引用指针并比较指针中存储的值。 a.Equals(b)在这里是真的。

如果您将b更改为:

b = "MYSTRING";

然后a.Equals(b)是假的,但是

a.Equals(b, StringComparison.OrdinalIgnoreCase) 

会是真的

a.CompareTo(b)调用字符串的CompareTo函数,该函数比较指针处的值,如果存储在a处的值小于存储在b处的值,则返回&lt; 0,如果a.Equals(b)则返回0为真,否则为> 0。但是,这是区分大小写的,我认为CompareTo可能有一些选项可以忽略大小写,但是现在没有时间看。 正如其他人已经说过的那样,这将用于分类。以这种方式比较相等会导致不必要的开销。

我确定我要把东西丢掉,但我认为如果你需要更多的细节,这应该是足够的信息来开始试验。