什么是 C# 中允许重复键的字典的替代方案
本文关键字:字典 方案 许重复 什么 | 更新日期: 2023-09-27 18:34:13
我有一个方法可以返回参与过某些项目的技术人员组,例如:
project 1 | John
project 1 | Tim
project 2 | John
project 2 | Dave
我最初尝试创建一个字典,它通常是我的首选键值对集合,但在这种情况下我无法使用它,因为我不能有重复的键(项目)。我可以使用的替代方案是什么?
我唯一的想法是创建一个Dictionary<Project, List<Technicians>>
但是有更简单的东西吗?
在您的情况下,同一个键与多个值相关,因此标准字典不合适。您可以像Dictionary<Key, List<Values>>
一样声明它.
但是,您也可以使用:
查找类,即
表示每个键映射到一个或多个值的键的集合。
为此,您需要框架 3.5 及更多。
Project
与一个或多个技术人员之间的关系:
public class Project
{
public ICollection<Technician> Technicians { get; set; }
}
var project = new Project();
project.Technicians = new List<Technician>()
{
new Technician(),
new Technician()
};
您的对象应该反映现实生活中的关系。
作为旁注,您可能有兴趣阅读有关域驱动设计的信息。
public void LoadTechnicians(Project project)
{
List<Technician> techs = new List<Technician>();
// query the database and map Technician objects
// Set the "Technicians" property
project.Technicians = techs;
}
<</div>
div class="answers"> 有一个来自 MS 的实验性 NuGet 包,其中包含 MultiValueDictionary
。
基本上,它就像 Dictionary<Project, List<Technicians>>
,除了您不必在每次访问它时重复所有逻辑来管理List
。
我认为您的解决方案没有任何问题。毕竟,您可以按项目轻松访问所有团队成员。但是您也可以尝试List<KeyValuePair<Project, Technician>>
。您可以保持键值关系,但不受不重复键的限制。它比你现在拥有的要简单得多吗?取决于用例。
或者,可以将此结构隐藏在自定义集合实现后面。
我已经从这篇文章中复制粘贴了我自己的答案。
很容易"滚动自己的"字典版本,允许"重复键"条目。这是一个粗略的简单实现。您可能需要考虑在 IDictionary<T>
上添加对基本上大多数(如果不是全部)的支持。
public class MultiMap<TKey,TValue>
{
private readonly Dictionary<TKey,IList<TValue>> storage;
public MultiMap()
{
storage = new Dictionary<TKey,IList<TValue>>();
}
public void Add(TKey key, TValue value)
{
if (!storage.ContainsKey(key)) storage.Add(key, new List<TValue>());
storage[key].Add(value);
}
public IEnumerable<TKey> Keys
{
get { return storage.Keys; }
}
public bool ContainsKey(TKey key)
{
return storage.ContainsKey(key);
}
public IList<TValue> this[TKey key]
{
get
{
if (!storage.ContainsKey(key))
throw new KeyNotFoundException(
string.Format(
"The given key {0} was not found in the collection.", key));
return storage[key];
}
}
}
有关如何使用它的快速示例:
const string key = "supported_encodings";
var map = new MultiMap<string,Encoding>();
map.Add(key, Encoding.ASCII);
map.Add(key, Encoding.UTF8);
map.Add(key, Encoding.Unicode);
foreach (var existingKey in map.Keys)
{
var values = map[existingKey];
Console.WriteLine(string.Join(",", values));
}