C#中Dictionary能否存在重复键对应不同值?
需求实现方案
这个需求完全可行,但注意**Dictionary<string, Things>本身不允许重复键**,直接用它存重复name的实例会抛出异常。你可以用以下两种方式实现:
方案一:使用Dictionary<string, List<Things>>
这种方式灵活性高,支持后续修改(添加/删除元素),是处理重复键字典的常用方案。
步骤:
- 先给
Things类新增location字段:
public class Things{ public string name; public int amount; public string colors; public string location; // 新增字段 //... }
- 反序列化JSON数据到
List<Things>,遍历填充字典并设置location:
// 以Newtonsoft.Json为例(也可使用System.Text.Json) using Newtonsoft.Json.Linq; using System.IO; using System.Collections.Generic; // 读取并解析JSON文件 var jsonContent = File.ReadAllText("你的JSON文件路径.json"); var jsonObj = JObject.Parse(jsonContent); var thingsList = jsonObj["Things"].ToObject<List<Things>>(); // 初始化字典 var myDictionary = new Dictionary<string, List<Things>>(); foreach (var thing in thingsList) { // 设置location字段值 thing.location = "home"; // 处理重复键:已存在则追加到列表,不存在则新建列表 if (myDictionary.ContainsKey(thing.name)) { myDictionary[thing.name].Add(thing); } else { myDictionary.Add(thing.name, new List<Things> { thing }); } }
方案二:使用Lookup<TKey, TElement>
Lookup是.NET提供的只读分组结构,专门用于一键多值的查询场景,无需手动处理重复键逻辑。
步骤:
同样先给
Things类新增location字段(与方案一一致)。反序列化数据并设置
location,再通过ToLookup生成分组结构:
using Newtonsoft.Json.Linq; using System.IO; using System.Linq; // 读取解析JSON var jsonContent = File.ReadAllText("你的JSON文件路径.json"); var jsonObj = JObject.Parse(jsonContent); var thingsList = jsonObj["Things"].ToObject<List<Things>>(); // 给每个实例设置location foreach (var thing in thingsList) { thing.location = "home"; } // 生成Lookup,按name分组 var myLookup = thingsList.ToLookup(t => t.name); // 访问示例:获取所有name为"cup"的实例 var cupItems = myLookup["cup"]; foreach (var item in cupItems) { // 处理每个item,比如输出信息 Console.WriteLine($"name: {item.name}, amount: {item.amount}, location: {item.location}"); }
两种方案对比:
Dictionary<string, List<Things>>:可读写,适合需要动态修改数据的场景。Lookup<TKey, TElement>:只读,创建后无法修改,但分组逻辑更简洁,适合仅查询的场景。
你不需要同时结合Dictionary和Lookup,根据自身场景选择其中一种即可。
内容的提问来源于stack exchange,提问作者1026
相关产品推荐
相关产品推荐

