C# LINQ中Equals及EqualSequence判断相等对象列表为何返回false
C# LINQ 中
Equals与SequenceEqual判断列表相等返回false的原因 首先纠正一个方法名笔误:LINQ中用于按顺序比较序列元素的方法是SequenceEqual,不存在名为EqualSequence的内置方法。
两个方法都返回false是C#默认相等比较逻辑的正常表现,具体原因分两点:
- 直接对List对象调用
Equals返回false:.NET中引用类型的默认Equals实现判断的是引用相等,也就是只有两个变量指向内存中同一个对象实例时才会返回true。哪怕两个列表的元素、顺序完全一致,只要是分别实例化的两个独立List对象,直接调用Equals必然返回false,和列表存储的内容无关。 - 调用
SequenceEqual返回false:SequenceEqual会逐对比较两个序列同位置的元素,默认使用元素类型的内置相等比较逻辑。如果你的列表存储的是自定义类对象(而非int、string这类原生实现了值相等判断的类型),自定义类的默认相等判断同样是引用相等规则:哪怕两个对象的所有属性值完全相同,只要是分别new出来的独立实例,默认比较就会判定二者不相等,最终导致SequenceEqual返回false。
可行的解决方法
你可以根据自己的场景选以下任意一种方案实现按内容比较:
- 为自定义元素类型实现值相等逻辑:让自定义类实现
IEquatable<T>接口,重写Equals和GetHashCode方法,按实际业务需求写属性值比较规则,之后直接调用SequenceEqual就会按值判断。 - 调用
SequenceEqual时传入自定义比较器,不需要修改原有类的定义,示例代码:
// 假设列表元素是Person类型,包含Name、Age两个属性 public class PersonComparer : IEqualityComparer<Person> { public bool Equals(Person x, Person y) { if (ReferenceEquals(x, y)) return true; if (x is null || y is null) return false; return x.Name == y.Name && x.Age == y.Age; } public int GetHashCode(Person obj) { return obj is null ? 0 : HashCode.Combine(obj.Name, obj.Age); } } // 比较时传入比较器实例 bool listEqual = list1.SequenceEqual(list2, new PersonComparer());
- 临时比较无需额外写类,可以利用匿名类型默认支持值相等的特性,投影要比较的属性后再调用
SequenceEqual:
bool listEqual = list1 .Select(p => new { p.Name, p.Age }) // 选择需要参与比较的属性 .SequenceEqual(list2.Select(p => new { p.Name, p.Age }));
调试两个对象列表的Equals和SequenceEqual结果截图
内容的提问来源于stack exchange,提问作者FriendNotFoe
相关产品推荐
相关产品推荐

