解决List<List<ScheduleStudyTime>>求公共项时匹配却返回空的问题
问题根源分析
你遇到的问题核心在于**Intersect方法默认的相等判断逻辑**:对于自定义引用类型ScheduleStudyTime,Intersect默认比较的是对象的引用(即是否是同一个内存实例),而不是对象的属性值。即使两个ScheduleStudyTime实例的所有属性值完全一致,只要它们是不同的对象(比如你在LINQ查询里new出来的不同实例),Intersect就会认为它们不相等,最终导致交集为空。
解决方案
针对这个问题,有两种常用的解决方式,你可以根据实际场景选择:
方式一:重写ScheduleStudyTime的Equals和GetHashCode方法
让类自己定义“相等”的规则——基于属性值来判断两个实例是否相等。修改你的ScheduleStudyTime类,添加以下方法:
private class ScheduleStudyTime { public int STUDTIME_ID { get; set; } public int DAY_ID { get; set; } public int LESSTIME_ID { get; set; } public int SCHOOLYEAR_ID { get; set; } // 重写Equals方法,基于属性值判断相等 public override bool Equals(object obj) { if (obj is not ScheduleStudyTime other) return false; return STUDTIME_ID == other.STUDTIME_ID && DAY_ID == other.DAY_ID && LESSTIME_ID == other.LESSTIME_ID && SCHOOLYEAR_ID == other.SCHOOLYEAR_ID; } // 重写GetHashCode,确保相等的实例返回相同的哈希码 public override int GetHashCode() { return HashCode.Combine(STUDTIME_ID, DAY_ID, LESSTIME_ID, SCHOOLYEAR_ID); } }
修改后,Intersect就会按照你定义的属性值规则来判断相等,能正确找出所有列表的公共实例。
方式二:使用Intersect的重载方法,传入自定义相等比较器
如果无法修改ScheduleStudyTime类(比如它是自动生成的实体类),可以定义一个单独的相等比较器,在调用Intersect时传入:
第一步:定义比较器类
private class ScheduleStudyTimeComparer : IEqualityComparer<ScheduleStudyTime> { public bool Equals(ScheduleStudyTime x, ScheduleStudyTime y) { if (x == null || y == null) return x == y; // 两个都为空则相等,一个为空一个不为空则不相等 return x.STUDTIME_ID == y.STUDTIME_ID && x.DAY_ID == y.DAY_ID && x.LESSTIME_ID == y.LESSTIME_ID && x.SCHOOLYEAR_ID == y.SCHOOLYEAR_ID; } public int GetHashCode(ScheduleStudyTime obj) { if (obj == null) return 0; return HashCode.Combine(obj.STUDTIME_ID, obj.DAY_ID, obj.LESSTIME_ID, obj.SCHOOLYEAR_ID); } }
第二步:修改Aggregate中的Intersect调用
var commonStudyTime = studyTimeList.Aggregate((xs, ys) => xs.Intersect(ys, new ScheduleStudyTimeComparer()).ToList());
额外注意点
如果studyTimeList中存在空列表或者null列表,Aggregate会直接返回空集合(因为空列表和任何列表的交集都是空)。你可以先过滤掉这些无效列表,避免意外结果:
// 过滤掉空列表和null列表 var validStudyTimeLists = studyTimeList.Where(list => list != null && list.Any()).ToList(); if (!validStudyTimeLists.Any()) { commonStudyTime = new List<ScheduleStudyTime>(); } else { commonStudyTime = validStudyTimeLists.Aggregate((xs, ys) => xs.Intersect(ys, new ScheduleStudyTimeComparer()).ToList()); }
内容的提问来源于stack exchange,提问作者Nineor
相关产品推荐
相关产品推荐

