使用 enumerable.except 忽略大小写判断差异,最直接的办法是传入一个自定义的 iequalitycomparer。通过实现 gethashcode 和 equals 方法,让比较逻辑基于 stringcomparison.ordinalignorecase,即可在保持集合去重特性的同时,不区分大小地剔除重复项。

如何为字符串集合定义忽略大小写的比较器?
要实现忽略大小写的比较,需要创建一个继承自 IEqualityComparer 的类。在这个类中,Equals 方法负责判断两个字符串是否相等,而 GetHashCode 方法负责生成哈希值。对于忽略大小写的场景,Equals应使用 OrdinalIgnoreCase 模式,而 GetHashCode 则必须对字符串进行统一的大小写转换(如全部转为小写)后再生成哈希值,以确保相等的字符串拥有相同的哈希码。

using System;
using System.Collections.Generic;
public class CaseInsensitiveComparer : IEqualityComparer<string>
{
public bool Equals(string x, string y)
{
return string.Equals(x, y, StringComparison.OrdinalIgnoreCase);
}
public int GetHashCode(string obj)
{
if (obj == null) return 0;
return string.GetHashCode(obj.ToLowerInvariant(), StringComparison.OrdinalIgnoreCase);
}
}</string>
如何在 LINQ 查询中应用该比较器并验证结果?
在获取到自定义比较器实例后,只需将其作为第二个参数传递给 Except 方法。该方法会遍历第一个集合中的每个元素,并使用提供的比较器检查其是否存在于第二个集合中。如果存在,则该元素被排除;否则保留。这种方法适用于任何实现了 IEnumerable 的字符串集合,且能正确处理空值和引用类型。

using System;
using System.Linq;
using System.Collections.Generic;
class Program
{
static void Main()
{
var list1 = new List<string> { "Apple", "banana", "CHERRY" };
var list2 = new List<string> { "apple", "Banana", "grape" };
var comparer = new CaseInsensitiveComparer();
var result = list1.Except(list2, comparer).ToList();
Console.WriteLine(string.Join(", ", result));
}
}</string></string>
当输入包含 null 值时 Except 的行为是什么?
在默认情况下,string.Equals 允许 null 值参与比较,但我们的自定义 GetHashCode 中对 null 做了特殊处理返回 0。如果集合中包含 null,Except 会将它们视为相等的元素进行过滤。例如,若 list1 包含 null 而 list2 也包含 null,则 list1 中的 null 会被剔除。若 list2 中没有 null,则 list1 中的 null 会保留。这种行为符合 IEqualityComparer 的契约,即 Equals(null, null) 返回 true。











