我有一个方法可以返回曾参与某些项目的技术人员小组,例如:
project 1 | John
project 1 | Tim
project 2 | John
project 2 | Dave
我最初尝试创建一个通常是我的键值对集合的字典,但在这种情况下我无法使用它,因为我无法使用重复键(项目)。我可以使用什么替代方案?
我唯一的想法是创建一个Dictionary<Project, List<Technicians>>
,但有更容易的东西吗?
答案 0 :(得分:44)
在您的情况下,相同的密钥与多个值相关,因此标准字典不适合。您可以将其声明为Dictionary<Key, List<Values>>
。
但是,您也可以使用:
Lookup类,
表示每个映射到一个或多个值的键集合。
为此需要3.5及更多框架。
答案 1 :(得分:13)
您需要的是Project
与一名或多名技术人员之间的关系:
public class Project
{
public ICollection<Technician> Technicians { get; set; }
}
var project = new Project();
project.Technicians = new List<Technician>()
{
new Technician(),
new Technician()
};
你的物体应该反映现实生活中的关系。
作为旁注,您可能有兴趣阅读Domain-driven design。
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;
}
答案 2 :(得分:12)
有an experimental NuGet package from MS that contains MultiValueDictionary
。
基本上,它与Dictionary<Project, List<Technicians>>
类似,只是每次访问时都不必重复所有逻辑来管理List
。
答案 3 :(得分:4)
我认为您的解决方案没有任何问题。毕竟,您可以按项目轻松访问所有团队成员。但另外,您可以尝试List<KeyValuePair<Project, Technician>>
。您保持键值关系,但不限制不重复的键。你现在拥有的东西要简单得多吗?取决于用例。
或者,您可以在自定义集合实现后隐藏此结构。
答案 4 :(得分:0)
我已经从this post复制了自己的答案。
它很容易“滚动你自己的&#34;允许&#34;重复键&#34;的字典版本。条目。这是一个简单的粗略实现。您可能需要考虑在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));
}