Bob Wintemberg
Bob Wintemberg

Reputation: 3252

Doing a Cast Within a LINQ Query

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

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.

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

Upvotes: 30

Views: 57120

Answers (5)

Michael Damatov
Michael Damatov

Reputation: 15623

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

Upvotes: 3

Amy B
Amy B

Reputation: 110081

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

Upvotes: 1

Lucas
Lucas

Reputation: 17424

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.

Upvotes: 11

Jared
Jared

Reputation: 8600

yes you can do the following:

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

Upvotes: 1

Chris Ammerman
Chris Ammerman

Reputation: 15306

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.

Upvotes: 27

Related Questions