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

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

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

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


当前回答

正如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;

其他回答

在你列出的表格中,两者之间没有太大的区别。CompareTo最终调用CompareInfo方法,该方法使用当前区域性进行比较;Equals由==运算符调用。

如果考虑到过载,情况就不一样了。Compare和==只能使用当前区域性来比较字符串。等号和字符串。Compare可以接受一个StringComparison枚举参数,允许您指定区域性不敏感或大小写不敏感的比较。只有字符串。Compare允许您指定CultureInfo并使用默认区域性以外的区域性执行比较。

由于它的多功能性,我发现我使用了String。比任何其他比较方法都要比较;它可以让我精确地指定我想要的东西。

从MSDN:

CompareTo方法主要用于排序或 排序操作。它不应该用于初级 该方法调用的目的是确定两个字符串是否正确 等价的。要确定两个字符串是否等效,请调用 Equals方法。”

他们建议在仅寻找相等时使用. equals而不是. compareto。我不确定字符串类的. equals和==之间是否有区别。我有时会使用。equals或Object。在我自己的类中使用ReferenceEquals而不是==,以防稍后有人出现并为该类重新定义==操作符。

下面是这些函数的工作规则:

stringValue.CompareTo(otherStringValue)

Null出现在字符串之前 它使用CultureInfo.CurrentCulture.CompareInfo。比较,这意味着它将使用依赖于区域性的比较。这可能意味着ß将比较等于德国的SS,或类似

stringValue.Equals(otherStringValue)

Null不被认为等于任何东西 除非你指定了StringComparison选项,否则它将使用看起来像直接序号相等性检查的东西,即ß与SS在任何语言或文化中都不相同

stringValue == otherStringValue

与stringValue.Equals()不同。 ==运算符调用静态Equals(字符串a,字符串b)方法(该方法将转到内部的EqualsHelper进行比较。 在空字符串上调用. equals()会得到空引用异常,而on ==则不会。

对象。ReferenceEquals (stringValue otherStringValue)

只是检查引用是否相同,即它不只是两个具有相同内容的字符串,你是在比较字符串对象和它本身。


注意,对于上面使用方法调用的选项,有更多的重载选项来指定如何进行比较。

如果你只是想检查是否相等,我的建议是决定是否要使用文化相关的比较,然后根据选择使用. compareto或. equals。

关于字符串比较问题的很好的解释和实践可以在文章中找到:在Microsoft . net 2.0中使用字符串的新建议和在. net框架中使用字符串的最佳实践。


上述每一种方法(或其他方法)都有特定的目的。它们之间的关键区别是默认情况下使用哪种类型的StringComparison Enumeration。有以下几种选择:

CurrentCulture CurrentCultureIgnoreCase InvariantCulture InvariantCultureIgnoreCase 序数 OrdinalIgnoreCase

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

Ordinal Case-sensitive internal identifiers Case-sensitive identifiers in standards like XML and HTTP Case-sensitive security-related settings OrdinalIgnoreCase Case-insensitive internal identifiers Case-insensitive identifiers in standards like XML and HTTP File paths (on Microsoft Windows) Registry keys/values Environment variables Resource identifiers (handle names, for example) Case insensitive security related settings InvariantCulture or InvariantCultureIgnoreCase Some persisted linguistically-relevant data Display of linguistic data requiring a fixed sort order CurrentCulture or CurrentCultureIgnoreCase Data displayed to the user Most user input

注意,StringComparison枚举和字符串比较方法的重载从。net 2.0开始就存在了。


字符串。CompareTo方法

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

用法:

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

Thus

实现IComparable接口必须使用此方法

字符串。比较的方法

String类的静态成员,有很多重载。默认解释:CurrentCulture。

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

字符串。=方法

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

String类的相等方法包括静态Equals、静态操作符==和实例方法Equals。


StringComparer 类

还有另一种处理字符串比较的方法,尤其是用于排序的方法:

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

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

我遵循以下准则:

精确匹配:编辑:我以前总是使用==操作符,原则是在Equals(string, string)中使用对象==操作符来比较对象引用,但似乎str .Equals(strB)总体上仍然比string快1-11%。= (strA, strB), strA == strB,和string。CompareOrdinal(箍,strB)。我用一个秒表对被拘禁/非被拘禁的字符串值进行循环测试,具有相同/不同的字符串长度,以及不同的大小(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