Выполнение роли в запросе LINQ
Можно ли выполнить листинг в запросе 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
имеют тип Paragraph
... и т.д. и т.д.
Есть ли способ в запросе LINQ сообщить компилятору, что t
в from t in content.ChildControls
является TabSection
?
Ответы
Ответ 1
Попробуйте следующее:
from TabSection t in content.ChildControls
Кроме того, даже если это не было доступно (или для другого будущего сценария, с которым вы можете столкнуться), вы не будете ограничиваться преобразованием всего в Списки. Преобразование в список вызывает оценку запроса на месте. Но если вы удаляете вызов ToList, вы можете работать с типом IEnumerable, который будет продолжать откладывать выполнение запроса до фактической итерации или сохранения в реальном контейнере.
Ответ 2
В зависимости от того, что вы пытаетесь сделать, один из них может сделать трюк:
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> (), который передает результаты в указанный тип. Если какой-либо элемент не может быть запущен, генерируется исключение. Как упоминалось в Turbulent Intellect, вы должны воздерживаться от вызова ToList() как можно дольше или вообще избегать этого.
Ответ 3
List<TabSection> tabList = (from t in content.ChildControls
let ts = t as TabSection
where ts != null
select ts).ToList();
Ответ 4
да, вы можете сделать следующее:
List<TabSection> tabList = (from t in content.ChildControls
where t as TabSection != null
select t as TabSection).ToList();
Ответ 5
А вот форма метода запроса.
List<Line> parentLineList =
content.ChildControls.OfType<TabSections>()
.SelectMany(t => t.ChildControls.OfType<Paragraph>())
.SelectMany(p => p.ChildControls.OfType<Line>())
.ToList();