在LINQ查询中进行转换

时间:2020-03-06 14:59:12  来源:igfitidea点击:

是否可以在LINQ查询中进行强制转换(为编译器着想)?

以下代码并不可怕,但最好将其合并为一个查询:

Content content = dataStore.RootControl as Controls.Content;

List<TabSection> tabList = (from t in content.ChildControls
                            select t).OfType<TabSection>().ToList();

List<Paragraph> paragraphList = (from t in tabList
                                 from p in t.ChildControls
                                 select p).OfType<Paragraph>().ToList();

List<Line> parentLineList = (from p in paragraphList
                             from pl in p.ChildControls
                             select pl).OfType<Line>().ToList();

代码继续进行更多的查询,但要点是我必须从每个查询中创建一个列表,以便编译器知道content.ChildControls中的所有对象均为TabSection类型,并且所有t.ChildControls中的对象的类型是"段落" ...的类型,依此类推等等。

LINQ查询中是否有办法告诉编译器content.ChildControls中的from from t中的t中的t是TabSection?

解决方案

试试这个:

from TabSection t in content.ChildControls

同样,即使这不可用(或者针对我们可能遇到的其他将来的情况),也不会被限制为将所有内容都转换为列表。转换为列表会立即进行查询评估。但是,如果删除ToList调用,则可以使用IEnumerable类型,该类型将继续推迟查询的执行,直到我们实际迭代或者存储在实际容器中为止。

是的,我们可以执行以下操作:

List<TabSection> tabList = (from t in content.ChildControls
                            where t as TabSection != null
                            select t as TabSection).ToList();

根据我们要尝试执行的操作,其中一种可能会达到目的:

List<Line> parentLineList1 =
  (from t in content.ChildControls.OfType<TabSection>()
   from p in t.ChildControls.OfType<Paragraph>()
   from pl in p.ChildControls.OfType<Line>()
   select pl).ToList();

List<Line> parentLineList2 =
  (from TabSection t in content.ChildControls
   from Paragraph p in t.ChildControls
   from Line pl in p.ChildControls
   select pl).ToList();

请注意,其中一个使用的是我们正在使用的OfType <T>()。这将过滤结果并仅返回指定类型的项目。第二个查询隐式使用Cast <T>(),它将结果转换为指定的类型。如果无法投射任何项目,则会引发异常。正如动荡的智力提到的那样,我们应该避免尽可能长时间地调用ToList(),或者尝试完全避免使用它。

这是查询方法表格。

List<Line> parentLineList =
  content.ChildControls.OfType<TabSections>()
    .SelectMany(t => t.ChildControls.OfType<Paragraph>())
    .SelectMany(p => p.ChildControls.OfType<Line>())
    .ToList();

List<TabSection> tabList = (from t in content.ChildControls
                            let ts = t as TabSection
                            where ts != null
                            select ts).ToList();