温故知新,CSharp遇见字符串比较(String Comparison),更佳科学的比较字符串
背景
在C#中,我们经常会遇到需要比较字符串的场景,有时候甚至因为外部输入的不确定性,我们需要忽略大小写来进行比较,以达到判断业务的述求。
对字符串用法的建议
使用.NET进行开发时,请遵循以下简要建议比较字符串:
- 使用为字符串操作显式指定字符串比较规则的重载。通常情况下,这涉及调用具有
StringComparison
类型的参数的方法重载。 - 使用
StringComparison.Ordinal
或StringComparison.OrdinalIgnoreCase
进行比较,并以此作为匹配区域性不明确的字符串的安全默认设置。 - 将比较与
StringComparison.Ordinal
或StringComparison.OrdinalIgnoreCase
配合使用,以获得更好的性能。 - 向用户显示输出时,使用基于
StringComparison.CurrentCulture
的字符串操作。 - 当进行与语言(例如,符号)无关的比较时,使用非语言的
StringComparison.Ordinal
或StringComparison.OrdinalIgnoreCase
值,而不使用基于CultureInfo.InvariantCulture
的字符串操作。 - 在规范化要比较的字符串时,使用
String.ToUpperInvariant
方法而非String.ToLowerInvariant
方法。 - 使用
String.Equals
方法的重载来测试两个字符串是否相等。 - 使用
String.Compare
和String.CompareTo
方法可对字符串进行排序,而不是检查字符串是否相等。 - 在用户界面,使用区分区域性的格式显示非字符串数据,如数字和日期。使用格式以固定区域性使非字符串数据显示为字符串形式。
比较字符串时,请避免采用以下做法:
- 不要使用未显式或隐式为字符串操作指定字符串比较规则的重载。
- 在大多数情况下,不要使用基于
StringComparison.InvariantCulture
的字符串操作。其中的一个少数例外情况是,保存在语言上有意义但区域性不明确的数据。 - 不要使用
String.Compare
或CompareTo
方法的重载和用于确定两个字符串是否相等的返回值为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();
}
参考
- StringComparison 枚举
- String.ToUpperInvariant 方法
- String.Equals 方法
- CultureInfo.InvariantCulture 属性
- 有关比较 .NET 中字符串的最佳做法
- 如何搜索字符串
- 如何:比较 C# 中的字符串
- C# 字符串比较优化(StringComparison)
温故知新,CSharp遇见字符串比较(String Comparison),更佳科学的比较字符串的更多相关文章
- 写出一个程序,接受一个由字母和数字组成的字符串,和一个字符,然后输出输入字符串中含有该字符的个数。不区分大小写。java算法
知识点一:equalsIgnore 1.使用equals( )方法比较两个字符串是否相等.它具有如下的一般形式: boolean equals(Object str) 这里str是一个用来与调用字符串 ...
- 温故知新,CSharp遇见异步编程(Async/Await),聊聊异步编程最佳做法
什么是异步编程(Async/Await) Async/Await本质上是通过编译器实现的语法糖,它让我们能够轻松的写出简洁.易懂.易维护的异步代码. Async/Await是C# 5引入的关键字,用以 ...
- 为什么operator>>(istream&, string&)能够安全地读入长度未知的字符串?
一般而言,实现"读入用户输入的字符串",程序中自然不能对用户输入的长度有所限定.这在C++中很容易实现,而在C中确没那么容易. 这一疑问,我在刚学C++的时候也在脑中闪现过:不过很 ...
- JAVA字符串格式化String.format()的使用
JAVA字符串格式化-String.format()的使用常规类型的格式化 String类的format()方法用于创建格式化的字符串以及连接多个字符串对象.熟悉C语言的同学应该记得C语言的sprin ...
- JAVA字符串格式化-String.format()使用
传统型格类型 String类的format()方法用于创建格式化的字符串以及连接多个字符串对象. 熟悉C语言的同学应该记得C语言的sprintf()方法.两者有类似之处.format()方法有两种重载 ...
- 全面深入介绍C++字符串:string类
http://blog.csdn.net/liuliming3000/article/details/1809385 1 从C到C++ string类 2 string类的构造函数 3 string类 ...
- [No0000EC]C# 字符串(String)
在 C# 中,可以使用字符数组来表示字符串,但是,更常见的做法是使用 string 关键字来声明一个字符串变量.string 关键字是 System.String 类的别名. 创建 String 对象 ...
- 雷林鹏分享:C# 字符串(String)
C# 字符串(String) 在 C# 中,您可以使用字符数组来表示字符串,但是,更常见的做法是使用 string 关键字来声明一个字符串变量.string 关键字是 System.String 类的 ...
- JAVA字符串格式化-String.format()的使用 【生成随机数补0操作】
转: JAVA字符串格式化-String.format()的使用 常规类型的格式化 String类的format()方法用于创建格式化的字符串以及连接多个字符串对象.熟悉C语言的同学应该记得C语言的s ...
随机推荐
- Go快速入门(二)
提示:本系列文章适合有其他语音基础并对Go有持续冲动的读者 一.package介绍 Go语言的代码是通过package来组织的,package的概念和你知道的其它语言 里的libraries或者m ...
- Gaussian Mixture Model
Gaussian Mixture Model (GMM).事实上,GMM 和 k-means 很像,不过 GMM 是学习出一些概率密度函数来(所以 GMM 除了用在 clustering 上之外,还经 ...
- Linux useradd 命令介绍
Linux useradd 命令介绍 作者: Alan Formy-duval 译者: LCTT Brooke Lau | 2020-01-06 22:58 使用 useradd 命令来添加用户(并且 ...
- 3*060-A 日志记录
电路检修遇到的问题: 今天在检修一块3060-A电路板时 发现 3.3V烫 但是3.3V路上的电容并没有短路 于是拆单片机 拆RS232EN 拆 FM24V 最后发现 原来是 1117 ...
- getaddrinfo()函数详解-(转自 cxz2009)
1. 概述IPv4中使用gethostbyname()函数完成主机名到地址解析,这个函数仅仅支持IPv4,且不允许调用者指定所需地址类型的任何信息,返回的结构只包含了用于存储IPv4地址的空间.IPv ...
- MySQL中InnoDB存储引擎的实现和运行原理
InnoDB 存储引擎作为我们最常用到的存储引擎之一,充分熟悉它的的实现和运行原理,有助于我们更好地创建和维护数据库表. InnoDB 体系架构 InnoDB 主要包括了: 内存池.后台线程以及存储文 ...
- Django(48)drf请求模块源码分析
前言 APIView中的dispatch是整个请求生命过程的核心方法,包含了请求模块,权限验证,异常模块和响应模块,我们先来介绍请求模块 请求模块:request对象 源码入口 APIView类中di ...
- .NET Core Web API使用HttpClient提交文件的二进制流(multipart/form-data内容类型)
需求背景: 在需要通过服务端请求传递文件二进制文件流数据到相关的服务端保存时,如对接第三方接口很多情况下都会提供一个上传文件的接口,但是当你直接通过前端Ajax的方式将文件流上传到对方提供的接口的时候 ...
- 激光雷达Lidar Architecture and Lidar Design(上)
激光雷达Lidar Architecture and Lidar Design(上) 介绍 激光雷达结构: 基本条件 构型和基本布置 激光雷达设计: 基本思想和基本原则 总结 介绍 激光雷达结构是激光 ...
- 部署通用基础设施, 满足顶级 SLA 要求
部署通用基础设施, 满足顶级 SLA 要求 Telefónica 使用基于英特尔 至强 可扩展处理器和英特尔 傲腾 数据中心级固态盘 的 VMware 虚拟存储区域网络 (vSAN)* 架构,完成对高 ...