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
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.ChildControls
are of type TabSection
and all of the objects in t.ChildControls
are 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 t
in from t in content.ChildControls
is a TabSection
?
LINQ 查询中有没有办法告诉编译器t
infrom t in content.ChildControls
是TabSection
?
采纳答案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();