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

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

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

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


当前回答

如果你对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

其他回答

如果你对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

从MSDN:

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

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

不是性能通常有99%的时间你需要这样做,但是如果你不得不这样做在一个循环中数百万倍。我强烈建议你使用.Equals或= =因为当它发现一个字符不匹配它把整个事情是假的,但是如果你使用CompareTo就必须找出哪些字符小于另一个,从而导致稍差的性能。

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

使用. equals,你还可以获得StringComparison选项。对于忽略大小写和其他东西非常方便。

顺便说一句,这将计算为假

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

return a==b

因为==比较a和b(它们是指针)的值,只有当指针指向内存中的同一个对象时,这个函数才会求值为true。. equals解引用指针并比较指针上存储的值。 a = (b)在这里为真。

如果把b改成:

b = "MYSTRING";

那么a = (b)是假的,但是

a.Equals(b, StringComparison.OrdinalIgnoreCase) 

是正确的

a.CompareTo(b) calls the string's CompareTo function which compares the values at the pointers and returns <0 if the value stored at a is less than the value stored at b, returns 0 if a.Equals(b) is true, and >0 otherwise. However, this is case sensitive, I think there are possibly options for CompareTo to ignore case and such, but don't have time to look now. As others have already stated, this would be done for sorting. Comparing for equality in this manner would result in unecessary overhead.

我确定我遗漏了一些东西,但我认为如果你需要更多细节,这些信息应该足够开始试验了。

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