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

C#调用ToDictionary报重复键错误时如何定位问题重复键

问题描述

调用ToDictionary方法构造SortedDictionary时抛出异常:An item with the same key has already been added,现有try-catch逻辑仅能拿到通用异常提示,无法定位具体是哪个键重复导致执行失败,相关代码如下:

try
{
    var dict = new SortedDictionary<long, long>(ReturnGetReviewTemplates.ToDictionary(tuple => tuple.Item1.Id, tuple => tuple.Item2.ReviewId));
}
catch(Exception e)
{
    string error = e.InnerException.Message;
}
可行排查方案
  • 分组统计法定位重复键
    直接调用ToDictionary会在遇到第一个重复键时直接抛出异常且不携带键信息,可先对所有待处理数据按键分组,筛选出出现次数大于1的键,就是导致异常的重复项:
    // 提取所有重复键
    var duplicateKeys = ReturnGetReviewTemplates
        .GroupBy(t => t.Item1.Id)
        .Where(g => g.Count() > 1)
        .Select(g => g.Key)
        .ToList();
    
    if (duplicateKeys.Any())
    {
        // 此处打断点或打日志,duplicateKeys中存储的就是所有重复的键值
        // 可根据业务需求处理重复项:比如保留第一条数据、合并对应值等
    }
    
    // 处理完重复项后再构造字典,例如用DistinctBy去重保留首个元素
    var dict = new SortedDictionary<long, long>(
        ReturnGetReviewTemplates
            .DistinctBy(t => t.Item1.Id)
            .ToDictionary(t => t.Item1.Id, t => t.Item2.ReviewId)
    );
    
  • 逐行添加捕获定位
    若不想大幅改动原有逻辑,可以放弃直接用ToDictionary,手动循环逐次向字典添加元素,触发异常时可直接获取当前正在添加的重复键:
    var dict = new SortedDictionary<long, long>();
    foreach (var item in ReturnGetReviewTemplates)
    {
        long key = item.Item1.Id;
        long value = item.Item2.ReviewId;
        try
        {
            dict.Add(key, value);
        }
        catch (ArgumentException ex)
        {
            // 此处断点即可拿到触发异常的重复key,可直接记录到错误日志
            throw new Exception($"构造字典失败,重复键为:{key}", ex);
        }
    }
    
  • 版本适配提示
    注意:.NET 6 之前版本的ToDictionary方法抛出的异常不会携带具体重复键信息,只有.NET 6及以上版本的异常消息才会附带重复键值,上述两种手动排查方案不受版本限制,兼容性更好。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 23:27:35