C#如何判断两个SelectedListItem列表是否具有相同值
根因
SelectListItem是引用类型,默认的相等比较逻辑是对比对象的内存引用地址,而非属性值。你从两个数据库分别读取生成的列表元素是完全独立的实例,哪怕Value、Text、Selected属性完全一致,默认比较也会返回false,这就是你之前所有方法都不生效的原因。
解决方案
方案1:一次性快速对比(无需自定义类)
如果只需要单次对比,直接提取属性用匿名类型比较即可,匿名类型会自动实现基于所有属性值的相等判断:
要求元素顺序完全一致时使用
bool isEqual = listA.Count == listB.Count && listA.Select(a => new { a.Value, a.Text, a.Selected }) .SequenceEqual(listB.Select(b => new { b.Value, b.Text, b.Selected }));
不要求元素顺序、只判断包含的元素值集合一致时使用
bool isSetEqual = listA.Select(a => new { a.Value, a.Text, a.Selected }) .OrderBy(x => x.Value).ThenBy(x => x.Text) .SequenceEqual(listB.Select(b => new { b.Value, b.Text, b.Selected }) .OrderBy(x => x.Value).ThenBy(x => x.Text));
方案2:可复用对比逻辑
如果需要多次做SelectListItem的相等比较,可以自定义相等比较器,之后你之前尝试的SetEquals、Except、Contains方法都可以正常使用:
第一步:实现比较器
public class SelectListItemValueComparer : IEqualityComparer<SelectListItem> { public bool Equals(SelectListItem x, SelectListItem y) { if (ReferenceEquals(x, y)) return true; if (ReferenceEquals(x, null) || ReferenceEquals(y, null)) return false; return x.Value == y.Value && x.Text == y.Text && x.Selected == y.Selected; } public int GetHashCode(SelectListItem obj) { if (ReferenceEquals(obj, null)) return 0; var valueHash = obj.Value?.GetHashCode() ?? 0; var textHash = obj.Text?.GetHashCode() ?? 0; var selectedHash = obj.Selected.GetHashCode(); return HashCode.Combine(valueHash, textHash, selectedHash); } }
第二步:使用比较器完成对比
// 判断集合是否相等(不考虑顺序) var comparer = new SelectListItemValueComparer(); bool equal = new HashSet<SelectListItem>(listA, comparer).SetEquals(listB); // 查找两个列表的差异项 var listAOnly = listA.Except(listB, comparer).ToList(); var listBOnly = listB.Except(listA, comparer).ToList(); // 判断单个元素是否在列表中 bool contains = listA.Contains(listB[0], comparer);
注意事项
- 如果不需要对比
Selected选中状态,直接去掉比较逻辑中对应Selected属性的判断即可 - 如果业务上
Value属性是唯一标识,可以只对比Value属性进一步简化逻辑
内容的提问来源于stack exchange,提问作者Apuna12
相关产品推荐
相关产品推荐

