认为这是一个非常基本的问题,但这是我的第一个LINQ查询,我完全陷入困境:
我有一个包含字符串键和列表值的字典(请参阅下面的定义),并希望提取已通过字典键选择列表的特定类型列表的元素。
IDictionary<string, IList<MyBaseType>> dataItemMap;
MySubType扩展MyBaseType。
我的狡猾疑问是:
string identCode = "foo";
IEnumerable<MySubType> query =
from entry in dataItemMap
where entry.Key == identCode
select entry.Value.OfType<MySubType>();
错误消息(来自LinqPad):
Cannot implicitly convert type
'System.Collections.Generic.IEnumerable<System.Collections.Generic.IEnumerable<MySubType>>'
to 'System.Collections.Generic.IEnumerable<MySubType>'.
An explicit conversion exists (are you missing a cast?)
问题显然在条目中.Value.OfType&lt;&gt;但是如何指定列表元素?我正在寻找像entry.Value.Items.OfType&lt;&gt;这样的东西。 ?
感谢。
答案 0 :(得分:8)
我想你想要这样的东西:
IEnumberable<MySubType> query = dataItemMap[identCode].OfType<MySubType>();
这将获得具有给定键的列表,然后过滤它以仅返回MySubType元素。
答案 1 :(得分:3)
两个警告:
identCode
和字典键的序数,文化不敏感的比较;使用字典查找将使用它构造的任何比较器。identCode
,您当前的代码将返回空序列;字典索引器会抛出异常。如果您想避免这种情况,可以使用TryGetValue
。请注意,如果您知道上次挑选的所有元素都是实际的正确类型,那么使用Cast
可能比{{1}更好}:
OfType
当两者都有效时,我通常更喜欢var query = dataItemMap[identCode].Cast<MySubType>();
到Cast
,因为这意味着如果我对序列中数据的假设不正确,我会发现它有异常,而不是默默地丢失数据
请注意,OfType
也会返回Cast
元素,而null
则不会。
不,问题不在于使用OfType
- 这是因为你最终得到了一系列序列,但是你试图将它分配给一个序列。
更改返回类型,或使用其他OfType<>
子句展平结果:
from
我很想直接使用扩展方法:
IEnumerable<MySubType> query = from entry in dataItemMap
where entry.Key == identCode
from value in entry.Value.OfType<MySubType>()
select value;