在C#中无需考虑大小写比较字符串

13

假设我有两个字符串:a 和 b。为了比较在忽略大小写的情况下 a 和 b 是否具有相同的值,我一直使用以下方法:

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

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

但是,使用Reflector,我在.NET Framework中见过这样的情况:

// (arg three is ignoreCase)

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

我测试了一下哪种方法更快,发现在我使用的字符串中,ToLower()Compare()每次都要快。

那么,为什么要使用Compare()而不是ToLower()呢?是因为CultureInfo的差异吗?我很困惑。

6个回答

23

您应该关注的主要问题不是性能,而是正确性。从这个角度来看,您可能想要使用的不区分大小写比较方法是:

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

或者

a.Equals(b, StringComparison.OrdinalIgnoreCase)

如果您知道字符串可能为空,则第一个选项很有用;如果您已经知道至少有一个字符串不为空,则后者更容易编写。我从未测试过性能,但假设它将是类似的。

OrdinalOrdinalIgnoreCase是一个安全的选择,除非您知道要使用另一种比较方法;若要获取所需信息以做出决策,请阅读此MSDN文章


在这里+1 - 性能并不重要。如果你达到了一个使用稍微低效的字符串比较方法会导致性能问题的点,那么你需要重新考虑你的方法。 - Rex M
1
微软建议不要使用string.Compare()来检查相等性。有一个等效的string.Equals()可以处理空值检查。我建议使用string.Equals(a, b, StringComparison.OrdianlIgnoreCase); - JSwartzen
如果字符串可以为空,我希望会出现 NullReferenceException 而不是错误的结果。因为你不能将“无”与“有”进行比较。在极少数情况下,如果 null 是有意义的,我会事先检查是否为 null 并返回 false,而不是用一个用于替换 Equalscompare 函数来代替它,从而使代码变得晦涩难懂。 - Maarten Bodewes

6

MSDN文章中的“备注”部分应该会解释这个问题。本质上,这样做是为了在不同文化环境下实现兼容性。


3
比较字符串时,您应该始终使用显式的StringComparison成员。String函数在选择比较字符串方面有些不一致。保证使用的比较方式的唯一方法是a)记忆它们所有(这包括您和您团队中的每个人)或b)为每个函数使用显式的比较方式。
最好明确表达,并不依赖于团队知识的完美性。你的队友会感谢你的。
示例:
if ( StringComparison.OrdinalIgnoreCase.Equals(a,b) )

使用ToLower进行比较有两个问题,我能想到的:

  1. 它会分配内存。除非绝对必要,比较函数不应该分配内存。
  2. 字符串可以通过几种方式转为小写。最明显的是按序数或按区域设置进行小写处理。ToLower()是哪种方式?就我个人而言,我不知道。最好传递一个明确的区域设置,而不是依赖默认设置。

2
那个不能编译。你是不是想说:String.Equals(a, b, StringComparison.OrdinalIgnoreCase.Equals) - Avi Cherry
我不知道,我看了微软的文档,也没有真正弄清楚OrdinalIgnoreCase到底是在做什么。我猜它只能将ASCII或Latin大写或小写,但这只是一个猜测。 - Maarten Bodewes

0

ToLower()不是一个比较函数,它将字符串转换为小写。当在C#中的String对象上使用==运算符时,编译器会进行优化。在核心上,两者都依赖于在反射器中看到的System.String.Equals。


他的意思是ToLower()示例打败了(显式)Compare()示例。 - strager
@Chris,国际化可能在其中发挥作用。 - strager
好的,那么 string.Compare(a.ToLower(), b.ToLower()) 似乎比 string.Compare(a, b, true) 更快。 - core

0

0

你能发一下你的测试代码吗?以证明调用ToLower()比不区分大小写的比较更快?我的测试结果恰恰相反!无论如何,其他回帖者提到的正确性问题是有道理的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接