关于.net:无情地比较C#中的字符串

Caselessly comparing strings in C#

假设我有两个字符串:a和b。为了比较忽略case时a和be是否具有相同的值,我总是使用:

1
2
3
// (Assume a and b have been verified not to be null)

if (a.ToLower() == b.ToLower())

但是,使用Reflector,我在.NET框架中见过几次:

1
2
3
// (arg three is ignoreCase)

if (string.Compare(a, b, true) == 0)

我测试了哪个更快,每次用我用的弦,ToLower()都打败了Compare()

有没有理由用Compare()代替ToLower()?关于不同的CultureInfo有什么?我在挠头。


您应该关注的主要问题不是性能,而是正确性,从这一方面来说,您可能希望用于不区分大小写比较的方法是:

1
string.Compare(a, b, StringComparison.OrdinalIgnoreCase) == 0;

1
a.Equals(b, StringComparison.OrdinalIgnoreCase)

(如果您知道字符串可能为空,则第一个字符串很有用;如果您已经知道至少有一个字符串为非空,则第二个字符串更容易编写。我从未测试过性能,但假设它是相似的。)

OrdinalOrdinalIgnoreCase是一个安全的赌注,除非你知道你想使用另一种比较方法;要获得做出决定所需的信息,请阅读msdn上的这篇文章。


MSDN文章的备注部分应该解释一些事情。从本质上讲,原因在于不同文化背景下的兼容性。


比较字符串时,应始终使用显式StringComparison成员。字符串函数在选择比较字符串的方式上有些不一致。确保所使用的比较的唯一方法是a)记住所有的比较(包括您和您团队中的每个人),或b)对每个函数使用显式比较。

最好是直截了当,不要依赖于群体知识的完善。你的队友会为此感谢你的。

例子:

1
if ( StringComparison.OrdinalIgnoreCase.Equals(a,b) )

使用Tolower进行比较有两个问题,我可以想得很清楚

  • 它分配内存。比较函数不应该分配内存,除非它们必须分配内存。
  • 弦可以通过多种方式降低。最显著的序数或文化敏感度较低。.tolower()的工作方式是什么?我个人不知道。传递一个明确的文化比依赖默认文化要好得多。

  • 你的测试显示调用tolower()比不区分大小写的比较快吗?我的测试显示相反的是真的!不管怎样,其他海报关于正确性的观点是站在一边的。


    另一篇提供了在各种情况下使用什么比较方法的注意事项和注意事项以及建议的msdn文章:关于在Microsoft.NET 2.0中使用字符串的新建议


    to lower()不是比较函数,它将字符串放在小写。当==运算符用于C中的字符串对象时,编译器会对其进行优化。在核心,两者都依赖于System.String.Equals,如Reflector中所示。