You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在.NET 3.1中用LINQ合并含相同screenID的列表并处理属性

解决.NET 3.1中LINQ合并两个列表并按规则去重的问题

问题原因

你用Union方法没去重的核心原因是:Union默认的相等比较逻辑不是只看screenID。如果你的ScreenPermission是类,它默认比较对象引用;如果是结构体,则比较所有字段的值。由于List1和List2中同screenID的条目其他属性(比如Print)不同,Union会把它们判定为不同对象,因此不会去重。

正确实现方案

我们需要先提取所有唯一的screenID,再针对每个ID按规则合并属性。推荐用字典来提升查找效率,具体步骤如下:

1. 定义实体类(如果还没定义)

假设你的权限实体是这样的:

public class ScreenPermission
{
    public int ScreenID { get; set; }
    public bool Create { get; set; }
    public bool Read { get; set; }
    public bool Update { get; set; }
    public bool Delete { get; set; }
    public bool Print { get; set; }
}

2. 合并逻辑代码

// 先把两个列表转成字典,用screenID做键,快速查找
var list1Dict = list1.ToDictionary(sp => sp.ScreenID);
var list2Dict = list2.ToDictionary(sp => sp.ScreenID);

// 获取所有不重复的screenID
var allScreenIds = list1Dict.Keys.Union(list2Dict.Keys);

// 遍历每个ID,按规则合并属性
var finalList = allScreenIds.Select(id => 
{
    // 尝试从两个字典中取出对应条目
    list1Dict.TryGetValue(id, out var list1Item);
    list2Dict.TryGetValue(id, out var list2Item);

    // 分三种情况处理
    if (list1Item != null && list2Item != null)
    {
        // 两个列表都有该ID,按规则合并:List1属性为true且List2为false时取true,否则false
        return new ScreenPermission
        {
            ScreenID = id,
            Create = list1Item.Create && !list2Item.Create,
            Read = list1Item.Read && !list2Item.Read,
            Update = list1Item.Update && !list2Item.Update,
            Delete = list1Item.Delete && !list2Item.Delete,
            Print = list1Item.Print && !list2Item.Print
        };
    }
    else if (list1Item != null)
    {
        // 只有List1有该ID,直接保留原条目
        return list1Item;
    }
    else
    {
        // 只有List2有该ID,按规则所有属性为false(因为List1属性默认是false)
        return new ScreenPermission
        {
            ScreenID = id,
            Create = false,
            Read = false,
            Update = false,
            Delete = false,
            Print = false
        };
    }
}).ToList();

3. 结果验证

针对你的示例数据,最终的finalList会是:

  • screenID96:Print为true,其余属性为false
  • screenID97:Print为true,其余属性为false
  • screenID98:保留List1的所有属性(全为true)

替代方案(如果想继续用Union)

如果一定要用Union,你需要给ScreenPermission重写Equals和GetHashCode方法,让比较逻辑只看screenID,然后再通过额外步骤合并属性。但这种方式不如字典方案直观,且需要额外维护相等比较逻辑,不推荐初学者使用。


内容的提问来源于stack exchange,提问作者Mayar Khaskieh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 08:15:54