C#判断列表是否包含于另一列表:为何条件判断不生效?
问题分析与解决方案
先看你的代码逻辑:
List<short> delegatingUserRoles = await (from urols in _dbContext.UsersRoles join u in _dbContext.Users on urols.UserId equals u.UserId where (u.Username == delegation.UserDelegating) select urols.RoleId).Distinct().ToListAsync(); if (delegatingUserRoles.ConvertAll(i => (int)i).All(item => (delegation.UserSelectedRoles).Contains(item))){ //true }
核心问题:逻辑判断方向搞反了
你要验证的是delegation.UserSelectedRoles是delegatingUserRoles的子集,但当前代码的逻辑是检查delegatingUserRoles转int后的所有元素,是否都存在于UserSelectedRoles中。
拿你举的例子来说:delegatingUserRoles是[1,2,3,4],转int后还是这四个数;UserSelectedRoles是[1,2,3]。此时All(item => UserSelectedRoles.Contains(item))会检查4是否在Selected里——显然不在,所以整个条件返回false,自然进不了if分支。
修正方案
要验证子集关系,应该反过来:检查UserSelectedRoles的所有元素,是否都存在于转int后的delegatingUserRoles中:
// 先把delegatingUserRoles转成int集合,避免重复转换 var delegatingRolesInt = delegatingUserRoles.ConvertAll(i => (int)i); if (delegation.UserSelectedRoles.All(item => delegatingRolesInt.Contains(item))){ // 这里会正常进入分支 }
额外优化建议
可以把转int后的集合改成HashSet<int>,Contains操作的时间复杂度从O(n)降到O(1),数据量大时性能更好:
var delegatingRolesSet = new HashSet<int>(delegatingUserRoles.ConvertAll(i => (int)i)); if (delegation.UserSelectedRoles.All(item => delegatingRolesSet.Contains(item))){ // 逻辑不变,性能更优 }
内容的提问来源于stack exchange,提问作者user18363545
相关产品推荐
相关产品推荐

