C# 在 LINQ 查询中执行强制转换

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/158634/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 16:07:17  来源:igfitidea点击:

Doing a Cast Within a LINQ Query

提问by Bob Wintemberg

Is it possible to do a cast within a LINQ query (for the compiler's sake)?

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

The following code isn't terrible, but it would be nice to make it into one query:

下面的代码并不可怕,但最好将它变成一个查询:

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();

The code continues on with a few more queries, but the gist is I have to create a List out of each query in order for the compiler to know that all of the objects in content.ChildControlsare of type TabSectionand all of the objects in t.ChildControlsare of type Paragraph...and so on and and so forth.

代码继续执行更多查询,但要点是我必须从每个查询中创建一个 List,以便编译器知道 中的所有对象content.ChildControls都是 typeTabSection并且中的所有对象t.ChildControls都是 type Paragraph。 ..等等等等。

Is there a way within the LINQ query to tell the compiler that tin from t in content.ChildControlsis a TabSection?

LINQ 查询中有没有办法告诉编译器tinfrom t in content.ChildControlsTabSection?

采纳答案by Chris Ammerman

Try this:

尝试这个:

from TabSection t in content.ChildControls

Also, even if this were not available (or for a different, future scenario you may encounter), you wouldn't be restricted to converting everything to Lists. Converting to a List causes query evaluation on the spot. But if you removing the ToList call, you could work with the IEnumerable type, which would continue to defer the execution of the query until you actually iterate or store in a real container.

此外,即使这不可用(或对于您可能遇到的不同的未来场景),您也不会被限制为将所有内容转换为列表。转换为 List 会导致当场查询评估。但是,如果您删除 ToList 调用,您可以使用 IEnumerable 类型,它会继续推迟查询的执行,直到您实际迭代或存储在真正的容器中。

回答by Jared

yes you can do the following:

是的,您可以执行以下操作:

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

回答by Lucas

Depending on what you are trying to do, one of these might do the trick:

根据您尝试执行的操作,其中之一可能会奏效:

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();

Note that one uses OfType<T>(), which you were using. This will filter the results and return only the items of the specified type. The second query implicitly uses Cast<T>(), which casts the results into the specified type. If any item cannot be cast, an exception is thrown. As mentioned by Turbulent Intellect, you should refrain from calling ToList() as long as possible, or try to avoid it altogether.

请注意,其中一个使用了您正在使用的 OfType<T>()。这将过滤结果并仅返回指定类型的项目。第二个查询隐式使用 Cast<T>(),它将结果转换为指定的类型。如果任何项目无法转换,则抛出异常。正如 Turbulent Intellect 所提到的,您应该尽可能长时间地避免调用 ToList(),或者尽量避免它。

回答by Amy B

And here's the query method form.

这是查询方法表单。

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

回答by Michael Damatov

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