ToList() 使用IEnumerable<T>并将其转换为 List<T>,那么 ToDictionary()也是类似的。大多数情况ToDictionary()是一个非常方便的方法,将查询的结果(或任何 IEnumerable<T>)转换成一个Dictionary<TKey,TValue>。 关键是您需要定义T如何分别转换TKey和TValue。
如果说我们有超级大的产品列表,希望把它放在一个Dictionary<int, product>,这样我们可以根据ID得到最快的查找时间。 你可能会这样做:
var results = new Dictionary<int, Product>(); foreach (var product in products) { results.Add(product.Id, product); }
和它看起来像一个很好的代码,但是我们可以轻松地使用LINQ而无需手写一大堆逻辑:
var results = products.ToDictionary(product => product.Id);
它构造一个Dictionary<int, Product> ,Key是产品的Id属性,Value是产品本身。 这是最简单的形式ToDictionary(),你只需要指定一个key选择器。 如果你想要不同的东西作为你的value? 例如如果你不在乎整个Product,,你只是希望能够转换ID到Name? 我们可以这样做:
var results = products.ToDictionary(product => product.Id, product => product.Name);
这将创建一个 Key为Id,Value为Name 的Dictionary<int, string>,。由此来看这个扩展方法有很多的方式来处理IEnumerable<T> 集合或查询结果来生成一个dictionary。
注:还有一个Lookup<TKey, TValue>类和ToLookup()扩展方法,可以以类似的方式做到这一点。 他们不是完全相同的解决方案(Dictionary和Lookup接口不同,他们的没有找到索引时行为也是不同的)。
因此,在我们的Product 示例中,假设我们想创建一个Dictionary<string, List<Product>> ,Key是分类,Value是所有产品的列表。 在以前你可能自实现自己的循环:
1 // create your dictionary to hold results 2 var results = new Dictionary<string, List<Product>>(); 3 4 // iterate through products 5 foreach (var product in products) 6 { 7 List<Product> subList; 8 9 // if the category is not in there, create new list and add to dictionary 10 if (!results.TryGetValue(product.Category, out subList)) 11 { 12 subList = new List<Product>(); 13 results.Add(product.Category, subList); 14 } 15 16 // add the product to the new (or existing) sub-list 17 subList.Add(product); 18 }
但代码应该更简单! 任何新人看着这段代码可能需要去详细分析才能完全理解它,这给维护带来了困难
幸运的是,对我们来说,我们可以利用LINQ扩展方法GroupBy()提前助力ToDictionary()和ToList():
// one line of code! var results = products.GroupBy(product => product.Category) .ToDictionary(group => group.Key, group => group.ToList());
GroupBy()是用Key和IEnumerable创建一个IGrouping的LINQ表达式查询语句。 所以一旦我们使用GroupBy() ,所有我们要做的就是把这些groups转换成dictionary,所以我们的key选择器 (group => group.Key) 分组字段(Category),使它的成为dictionary的key和Value择器((group => group.ToList()) 项目,并将它转换成一个List<Product>作为我们dictionary的Value!
这样更容易读和写,单元测试的代码也更少了! 我知道很多人会说lamda表达式更难以阅读,但他们是c#语言的一部分,高级开发人员也必须理解。我认为你会发现当你越来越多的使用他们后,代码能被更好的理解和比以前更具可读性。