C#比较顺序无关的字符串嵌套List时Contains始终返回false
问题原因
List<T>的Contains()、Remove()方法对引用类型元素默认做引用相等判定:只有两个元素是同一个对象实例时才会判定为相等。
你代码中两个嵌套List里的子List都是单独new出来的独立实例,哪怕元素内容完全一致,默认比较逻辑也会判定为不匹配,所以会在注释标注的位置直接返回false。
你提到的SequenceEqual()本身是按内容顺序比较序列的,完全可以用来做子List的内容匹配,只是不能直接拿来比较外层嵌套List——因为你需要忽略外层子List的排列顺序。
修复实现
核心逻辑是自定义子List的匹配规则:按内容而非引用判断两个子List是否一致,操作目标集合的副本避免修改原始数据,匹配到对应子List后就移除,防止重复匹配。
场景1:子List内部元素顺序需要严格一致,仅外层子List顺序可忽略
这也是和你给出的测试用例预期一致的场景,实现代码如下:
using System.Collections.Generic; using System.Linq; private List<List<string>> testOrder = new List<List<string>> { new List<string> { "Burger", "Cheese" }, new List<string> { "Hot Dog", "Ketchup" } }; private List<List<string>> testOrder2 = new List<List<string>> { new List<string> { "Hot Dog", "Ketchup" }, new List<string> { "Burger", "Cheese" } }; public bool CheckOrder() { // 元素总数不一致直接判定不相等 if (testOrder.Count != testOrder2.Count) { return false; } // 创建待匹配列表的副本,避免修改原始集合产生副作用 var pendingMatch = testOrder2.Select(sub => sub.ToList()).ToList(); foreach (var targetSub in testOrder) { // 按内容顺序查找匹配的子List int matchPos = pendingMatch.FindIndex(candidate => candidate.SequenceEqual(targetSub)); if (matchPos == -1) { return false; } // 移除已匹配项,避免重复匹配 pendingMatch.RemoveAt(matchPos); } return true; }
场景2:子List内部元素顺序也可忽略
如果子List比如["Cheese", "Burger"]和["Burger", "Cheese"]也需要判定为相等,只需要把查找匹配的逻辑替换为不考虑内部元素顺序的判断即可:
// 忽略子List内部顺序的匹配规则 int matchPos = pendingMatch.FindIndex(candidate => candidate.Count == targetSub.Count && !candidate.Except(targetSub).Any() );
这种实现天然支持重复子List的匹配校验,比如两个嵌套List都包含2个内容完全一致的子List时,会正常判定为相等,不会出现漏判、错判。
内容的提问来源于stack exchange,提问作者jaredseale
相关产品推荐
相关产品推荐

