背景

在C#中,我们经常会遇到需要比较字符串的场景,有时候甚至因为外部输入的不确定性,我们需要忽略大小写来进行比较,以达到判断业务的述求。

对字符串用法的建议

使用.NET进行开发时,请遵循以下简要建议比较字符串:

  • 使用为字符串操作显式指定字符串比较规则的重载。通常情况下,这涉及调用具有StringComparison类型的参数的方法重载。
  • 使用StringComparison.OrdinalStringComparison.OrdinalIgnoreCase进行比较,并以此作为匹配区域性不明确的字符串的安全默认设置。
  • 将比较与StringComparison.OrdinalStringComparison.OrdinalIgnoreCase配合使用,以获得更好的性能。
  • 向用户显示输出时,使用基于StringComparison.CurrentCulture的字符串操作。
  • 当进行与语言(例如,符号)无关的比较时,使用非语言的StringComparison.OrdinalStringComparison.OrdinalIgnoreCase值,而不使用基于CultureInfo.InvariantCulture的字符串操作。
  • 在规范化要比较的字符串时,使用String.ToUpperInvariant方法而非String.ToLowerInvariant方法。
  • 使用String.Equals方法的重载来测试两个字符串是否相等。
  • 使用String.CompareString.CompareTo方法可对字符串进行排序,而不是检查字符串是否相等。
  • 在用户界面,使用区分区域性的格式显示非字符串数据,如数字和日期。使用格式以固定区域性使非字符串数据显示为字符串形式。

比较字符串时,请避免采用以下做法:

  • 不要使用未显式或隐式为字符串操作指定字符串比较规则的重载。
  • 在大多数情况下,不要使用基于StringComparison.InvariantCulture的字符串操作。其中的一个少数例外情况是,保存在语言上有意义但区域性不明确的数据。
  • 不要使用String.CompareCompareTo方法的重载和用于确定两个字符串是否相等的返回值为0的测试。

显式指定字符串比较

重载.NET中大部分字符串操作方法。通常,一个或多个重载会接受默认设置,然而其他重载则不接受默认设置,而是定义比较或操作字符串的精确方式。大多数不依赖于默认设置的方法都包括StringComparison类型的参数,该参数是按区域性和大小写为字符串比较显式指定规则的枚举。

StringComparison枚举成员

StringComparison 成员 描述
CurrentCulture 使用当前区域性执行区分大小写的比较。
CurrentCultureIgnoreCase 使用当前区域性执行不区分大小写的比较。
InvariantCulture 使用固定区域性执行区分大小写的比较。
InvariantCultureIgnoreCase 使用固定区域性执行不区分大小写的比较。
Ordinal 执行序号比较。
OrdinalIgnoreCase 执行不区分大小写的序号比较。

例如,IndexOf方法(它返回String对象中与某字符或字符串匹配的子字符串的索引)具有九种重载:

  • 默认情况下,IndexOf(Char),IndexOf(Char,Int32)IndexOf(Char,Int32,Int32)对字符串中的字符执行序号(区分大小写但不区分区域性的)搜索。
  • 默认情况下,IndexOf(String),IndexOf(String,Int32)IndexOf(String,Int32,Int32)对字符串中的子字符串执行区分大小写且区分区域性的搜索。
  • IndexOf(String,StringComparison)IndexOf(String,Int32,StringComparison)IndexOf(String,Int32,Int32,StringComparison),其中包括StringComparison类型的参数,该类型允许指定比较形式。

我们建议选择不使用默认值的重载,原因如下:

  • 具有默认参数的一些重载(在字符串实例中搜索Char的重载)执行序号比较,而其他重载(在字符串实例中搜索字符串的重载)执行的是区分区域性的比较。要记住哪种方法使用哪个默认值并非易事,并很容易混淆重载。

  • 依赖于方法调用默认值的代码的意图并不清楚。在下面依赖于默认值的示例中,很难了解开发人员对两个字符串的实际意图是执行序号比较还是语言比较,或者protocol和“http”之间存在的大小写差异是否会导致相等性测试返回false类型的参数的方法重载。

string protocol = GetProtocol(url);
if (String.Equals(protocol, "http")) {
// ...Code to handle HTTP protocol.
}
else {
throw new InvalidOperationException();
}

一般情况下,我们建议调用不依赖于默认设置的方法,因为这会明确代码的意图。这进而使代码更具可读性且更易于调试和维护。下面的示例解决了前面示例中提出的问题。使用序号比较并且忽略大小写差异。

string protocol = GetProtocol(url);
if (String.Equals(protocol, "http", StringComparison.OrdinalIgnoreCase)) {
// ...Code to handle HTTP protocol.
}
else {
throw new InvalidOperationException();
}

参考

温故知新,CSharp遇见字符串比较(String Comparison),更佳科学的比较字符串的更多相关文章

  1. 写出一个程序,接受一个由字母和数字组成的字符串,和一个字符,然后输出输入字符串中含有该字符的个数。不区分大小写。java算法

    知识点一:equalsIgnore 1.使用equals( )方法比较两个字符串是否相等.它具有如下的一般形式: boolean equals(Object str) 这里str是一个用来与调用字符串 ...

  2. 温故知新,CSharp遇见异步编程(Async/Await),聊聊异步编程最佳做法

    什么是异步编程(Async/Await) Async/Await本质上是通过编译器实现的语法糖,它让我们能够轻松的写出简洁.易懂.易维护的异步代码. Async/Await是C# 5引入的关键字,用以 ...

  3. 为什么operator>>(istream&, string&)能够安全地读入长度未知的字符串?

    一般而言,实现"读入用户输入的字符串",程序中自然不能对用户输入的长度有所限定.这在C++中很容易实现,而在C中确没那么容易. 这一疑问,我在刚学C++的时候也在脑中闪现过:不过很 ...

  4. JAVA字符串格式化String.format()的使用

    JAVA字符串格式化-String.format()的使用常规类型的格式化 String类的format()方法用于创建格式化的字符串以及连接多个字符串对象.熟悉C语言的同学应该记得C语言的sprin ...

  5. JAVA字符串格式化-String.format()使用

    传统型格类型 String类的format()方法用于创建格式化的字符串以及连接多个字符串对象. 熟悉C语言的同学应该记得C语言的sprintf()方法.两者有类似之处.format()方法有两种重载 ...

  6. 全面深入介绍C++字符串:string类

    http://blog.csdn.net/liuliming3000/article/details/1809385 1 从C到C++ string类 2 string类的构造函数 3 string类 ...

  7. [No0000EC]C# 字符串(String)

    在 C# 中,可以使用字符数组来表示字符串,但是,更常见的做法是使用 string 关键字来声明一个字符串变量.string 关键字是 System.String 类的别名. 创建 String 对象 ...

  8. 雷林鹏分享:C# 字符串(String)

    C# 字符串(String) 在 C# 中,您可以使用字符数组来表示字符串,但是,更常见的做法是使用 string 关键字来声明一个字符串变量.string 关键字是 System.String 类的 ...

  9. JAVA字符串格式化-String.format()的使用 【生成随机数补0操作】

    转: JAVA字符串格式化-String.format()的使用 常规类型的格式化 String类的format()方法用于创建格式化的字符串以及连接多个字符串对象.熟悉C语言的同学应该记得C语言的s ...

随机推荐

  1. jQ的四类基本选择器

    jQuery的四种选择器 jQ选择器与css选择器本质上相差不大,但是在使用容易混淆格式或属性 1.基础选择器 $('#id名') $('.类名') $('.类名1 .类名2') $('标签名.类名' ...

  2. prometheus nginx-module-vts删除内存区数据

    项目地址:https://github.com/vozlt/nginx-module-vts 删除所zone内存中的数据 curl localhost/status/control?cmd=delet ...

  3. Linux查看PCIe版本及速率# lspci -vvv |grep Width -i

    Linux查看PCIe版本及速率 https://www.cnblogs.com/lsgxeva/p/9542975.html# lspci -vvv |grep Width -i # lspci | ...

  4. [文章]Linux宕机故障分析案例

    [文章]Linux宕机故障分析案例 已采纳 收藏  0  1669 0 马化辉 2018-07-01发布 背景 在Linux系统环境下,服务器宕机发生的频率比较小,但是不少工程师或多或少都会遇到这 ...

  5. 在Linux中通过Top运行进程查找最高内存和CPU使用率

    按内存使用情况查找前15个进程,在批处理模式下为"top" 使用top命令查看有关当前状态,系统使用情况的更详细信息:正常运行时间,负载平均值和进程总数. 分类:Linux命令操作 ...

  6. 微信收藏了很多语音,有一些比较有意义的,但是发现只能收藏在微信,没有办法导出了,请大神看清楚,是微信【收藏】的语音,ios或者安卓的方法都可以

  7. 快成物流科技 x mPaaS | 小程序容器加持下的技术架构“提质增效”

      导言 从 2017 年开始,GMTC"移动技术大会"就更名为"大前端技术大会".发展至今,混合开发.原生开发.前端开发等概念正在深度融合,组成"大 ...

  8. pika详解(二) BlockingConnection

    pika详解(二) BlockingConnection   本文链接:https://blog.csdn.net/comprel/article/details/94592348 版权 Blocki ...

  9. CVD和ALD薄膜沉积技术应用领域

    CVD和ALD薄膜沉积技术应用领域 显示 用于OLED.QD-OLED.甚至未来QLED的薄膜封装,通过有机/无机叠层结构的保护,水汽渗透率WVTR可降至10-5g/m2/day,保证OLED或者量子 ...

  10. CodeGen概述

    CodeGen概述 CodeGen是在协同开发环境中工作的软件开发人员可以用来生成源代码的工具.该代码可能是Synergy DBL代码,也可能是其他语言的源代码.CodeGen并不局限于为任何特定的开 ...