在C#里比较两个字符串是否相等,最直接的想法就是用==运算符。但==和Equals默认都是区分大小写的,"Admin"和"admin"会被判定为不相等。实际业务中这种情况非常常见:登录时校验验证码、比对文件扩展名、匹配配置项的键名等,往往都希望忽略大小写。C#为此提供了完整的一套比较机制,核心是StringComparison枚举和StringComparer类,本文详细介绍它们的用法。

一、使用string.Equals配合StringComparison枚举
这是最常用也是最推荐的方式。Equals方法有一个重载,接受StringComparison枚举参数,通过传入StringComparison.OrdinalIgnoreCase即可实现忽略大小写的比较。
string a = "Admin"; string b = "admin"; // 区分大小写,结果为 false bool r1 = a.Equals(b); // 忽略大小写,结果为 true bool r2 = a.Equals(b, StringComparison.OrdinalIgnoreCase); // 静态方法写法,可以避免 a 为 null 时抛异常 bool r3 = string.Equals(a, b, StringComparison.OrdinalIgnoreCase);
这里推荐使用静态形式string.Equals(a, b, StringComparison.OrdinalIgnoreCase),因为当第一个字符串为null时,实例方法会抛出NullReferenceException,而静态方法内部做了空值处理,返回false,代码更健壮。
顺便提一句,很多初学者会用a.ToLower() == b.ToLower()来实现忽略大小写,这种写法虽然能出结果,但会额外创建两个新的字符串对象,在循环或高频调用场景下会产生不必要的内存分配,性能不如Equals重载,而且土耳其等文化区域下ToLower的行为还可能出问题,所以不建议使用。
二、使用StringComparer类设置比较规则
StringComparer是一个实现了IComparer<string>和IEqualityComparer<string>接口的类,它适合用在需要传入比较器的场合,比如字典、集合、排序方法等。StringComparer.OrdinalIgnoreCase是它的静态属性之一,代表忽略大小写的比较规则。
// 创建忽略大小写的字典,Key 为 "admin" 和 "ADMIN" 视为同一个键
var dict = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
dict["admin"] = 1;
Console.WriteLine(dict["ADMIN"]); // 输出 1
// 在排序时指定比较器
var list = new List<string> { "Banana", "apple", "Cherry" };
list.Sort(StringComparer.OrdinalIgnoreCase);StringComparer还提供了CurrentCultureIgnoreCase、InvariantCultureIgnoreCase等规则,区别在于它们会参考文化区域信息。比如在土耳其语文化中,字母I的小写形式不是i而是ı,使用文化相关的比较会产生意料之外的结果。除非确实需要按某种语言的规则比较,一般直接选OrdinalIgnoreCase即可。
如果需要动态判断,StringComparer也提供了Create方法,可以基于指定的CultureInfo和是否忽略大小写来构造自定义的比较器,适合多语言应用。
三、Compare、CompareTo与Contains等方法的应用
除了判断相等,有时候需要判断大小关系或判断包含关系,这些方法同样支持忽略大小写的重载。string.Compare返回整数:等于0表示两个字符串相同,小于0表示前者排在后者之前,大于0则相反。
string a = "Hello";
string b = "hello";
// 返回 0,表示忽略大小写后相等
int result = string.Compare(a, b, StringComparison.OrdinalIgnoreCase);
// StartsWith 和 EndsWith 也支持忽略大小写
string fileName = "REPORT.PDF";
bool isPdf = fileName.EndsWith(".pdf", StringComparison.OrdinalIgnoreCase); // true
// IndexOf 同样支持
string text = "Hello World";
int idx = text.IndexOf("WORLD", StringComparison.OrdinalIgnoreCase); // 返回 6判断文件扩展名是忽略大小写比较的典型场景。Windows文件系统不区分大小写,如果用默认的EndsWith(".pdf")去判断,遇到"REPORT.PDF"就会误判。而传入OrdinalIgnoreCase后无论扩展名是大写、小写还是混合大小写都能正确识别。
需要注意StartsWith的旧重载StartsWith(string)在部分.NET版本中已被标记为不推荐,编译器会给出警告,建议始终显式传入StringComparison参数,让代码意图更清晰,也避免潜在的文化相关问题。
四、Ordinal与Culture的比较规则怎么选
StringComparison枚举一共有六个值:CurrentCulture、CurrentCultureIgnoreCase、InvariantCulture、InvariantCultureIgnoreCase、Ordinal、OrdinalIgnoreCase。前面四个是文化相关比较,后两个是序号比较,也就是逐个字符按Unicode码位比较。
两者的核心区别在于:文化相关比较会按照特定语言的排序规则处理字符,比如德语中ö会被视为接近o,而序号比较中ö和o是完全不同的字符。文化比较需要查询文化数据表,性能明显低于序号比较。因此对于机器处理的字符串,也就是路径、URL、XML标签、HTTP头、GUID这类内容,微软官方明确建议使用Ordinal或OrdinalIgnoreCase。
文化相关比较只应该用于面向用户展示的文本,比如按本地语言习惯排序人名列表。如果一个忽略大小写的场景不知道该选哪个,选StringComparison.OrdinalIgnoreCase基本不会错,它既是性能最好的忽略大小写方案,也能避免不同区域设置下行为不一致的问题,这在服务器部署时尤其重要,因为服务器的区域设置可能与开发机不同。
总结一下常用的写法:判断相等用string.Equals(a, b, StringComparison.OrdinalIgnoreCase),字典和集合用StringComparer.OrdinalIgnoreCase初始化,前缀后缀匹配用带StringComparison参数的StartsWith和EndsWith。掌握这几个API,C#中忽略大小写的字符串比较就基本全覆盖了。
C#忽略大小写比较StringComparison字符串比较规则修改时间:2026-09-04 10:04:57