我有一个方法,可以返回曾在某些项目上工作的技术人员组,例如:
project 1 | John
project 1 | Tim
project 2 | John
project 2 | Dave
我原本尝试创建一个字典,而这通常是我使用的键值对集合,但在此情况下我无法使用它,因为我不能有重复的键(即项目)。有没有其他可以使用的替代方法?
我唯一想到的是创建一个Dictionary<Project, List<Technicians>>
,但是否有更简单的方法呢?
我有一个方法,可以返回曾在某些项目上工作的技术人员组,例如:
project 1 | John
project 1 | Tim
project 2 | John
project 2 | Dave
我原本尝试创建一个字典,而这通常是我使用的键值对集合,但在此情况下我无法使用它,因为我不能有重复的键(即项目)。有没有其他可以使用的替代方法?
我唯一想到的是创建一个Dictionary<Project, List<Technicians>>
,但是否有更简单的方法呢?
Dictionary<Key, List<Values>>
。ToLookup
扩展方法将序列或字典转换很容易。 - DennisLookup
是只读集合,只能从现有数据中使用LINQ创建。你不能自己实例化或改变它。 - vgruProject
类是首选,因为明显需要将一个项目与技术人员列表链接起来。如果不能更改 Project
类的源代码,可以考虑使用 Lookup
类或 Dictionary
,但是如果可以更改源代码,则有利于创建两个类之间的__清晰连接__。 - Greg BurghardtLookup
。 - AdamMc331List<Tuple>
的情况下,您无法像访问键一样访问它。 - Tigran项目
与一个或多个技术人员之间的关系: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;
}
Project
并且你需要所有的 Technicians
,那么在这个例子中,你只需要调用 Project
的一个属性,而不是将其输入到字典中并处理输出。这样做会更容易和更快。 - Servy有一款微软实验性NuGet包含有MultiValueDictionary
。
基本上,它就像Dictionary<Project, List<Technicians>>
,但是你不必每次访问时都重复管理List
的所有逻辑。
List<KeyValuePair<Project, Technician>>
。你可以保持键值关系,但不受不重复键的限制。这比你现在拥有的要简单得多吗?这取决于具体情况。
此外,你可以在自定义集合实现中隐藏此结构。HashSet<KeyValuePair<Project, Technician>>
? - Arturo Torres SánchezKeyValuePair
覆盖了Equals
,但事实上似乎并没有。那么我猜Tuple
可能是一个更好的选择(仍然使用HashSet
)。 - Arturo Torres Sánchez我从this post中复制粘贴了自己的答案。
编写一个允许“重复键”条目的字典版本非常容易。这里是一个简单的实现。您可能希望考虑添加对基本上大多数(如果不是全部)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));
}
Dictionary<Project, List<Technicians>>
看起来已经很不错了。但是如果你不需要将Project
作为键(即你不需要获取某个项目的所有技术人员),那么你可以尝试使用List<Tuple<Project, Technician>>
。 - Andrey Korneyev