我想写这个LINQ语句:
Dictionary<int, ItemBO> result = ( Dictionary<int, ItemBO> )
( from item in originalResults where item.Value.SomeCriteria == true
select item );
originalResults
的类型为Dictionary<int, ItemBO>
。
我认为item
的类型为KeyValuePair<int, ItemBO>
,但我认为从该类型的列表转换为该类型的词典会是......呃......“天然的”。
相反,为了让编译器闭嘴,我需要写一下:
Dictionary<int, ItemBO> result =
( from item in originalResults where item.Value.SomeCriteria == true
select item.Value ).ToDictionary( GetItemKey );
虽然并非完全违反直觉,但它表明,正在进行大量不必要的工作,打包和重新打包字典。有更好的解决方案吗?我错过了一个概念吗?
答案 0 :(得分:4)
虽然并非完全违反直觉,但它表明,正在进行大量不必要的工作,包括解包和重新包装词典。
我不确定“不必要的”工作是什么意思。要执行此操作需要大量工作 - 必须对查询进行全面评估,这涉及扫描整个字典并评估每个条目的谓词。此外,必须创建并填充新字典以存储结果。我认为如果通过自动转换隐藏这项工作会更有问题。
真正的问题是你向后使用你的字典。按键查找速度很快,但按值查找需要扫描字典中的所有项目。如果您可以存储字典,以便您用来过滤的值是关键,那么您将能够更快地查找并使用更清晰的语法。
答案 1 :(得分:2)
我将再次尝试你所缺少的真正的“关键”概念。
如果我想冒险,我会说我认为你想象一个Dictionary<TKey, TValue>
作为其内容的同义词。 你有一堆键值对 - 这是一本字典,对吗?这就是你错过重要细节的地方。虽然你肯定可以使用简单的IDictionary<TKey, TValue>
来实现KeyValuePair<TKey, TValue>[]
,但这将缺少首先使用字典类型的最大好处之一:快速查找按键。
即使您对数组进行了排序并使用二进制搜索来定位键(顺便说一下,这会导致所有插入的成本),您也无法与Dictionary<TKey, TValue>
{{1}}竞争使用。这种实现不仅仅是“一堆键值对”,没有特定的结构;结构是此类型的所有。因此,从一堆键值对(没有结构的内容)直接到字典(具有非常特殊的结构)的快速转换实际上是不可能的 - 不是类型的结构布局确实确定是否可以在无论如何C#(你必须单独遵守继承,并且一些内置的,可能还有用户定义的类型转换)。
这样想:字典是容器,而不是内容,对吧?所以,如果我有一罐不同类型的饼干,我想要拿出所有巧克力饼干,我可能会提取每一个,把它们全部放在一堆然后说:“现在这是一罐巧克力芯片饼干,对吧?“不,我只把饼干拿出来;我拥有的是一堆,而不是一个罐子。如果我想要巧克力饼干的 jar ,那么我将将它们放在一个中 - 这将需要一些非零工作量。
答案 2 :(得分:1)
您缺少的概念是您的代码代表现有字典的查询,其结果将是IEnumerable<KeyValuePair<K,V>>
。您的原始代码期望的是有人定义了IEnumerable<KeyValuePair<K,V>>
到Dictionary<K,V>
的转化。从本质上讲,他们已经让你能够定义自己需要的任何转换,因为你有ToDictionary
扩展方法,可以让你确定一个键,一个值等。
答案 3 :(得分:0)
linq查询的“真实”结果不是字典,因此您无法自然地进行转换。 结果是IQueryable,所以你必须明确地转换它。