Почему набор Средств управления не предоставляет все методы IEnumerable?

Я не наверняка, как ControlCollection работ ASP.NET, поэтому возможно, кто-то может пролить некоторый свет на это для меня.

Я недавно обнаружил волшебство, которое является дополнительными методами и Linq. Ну, мне было очень грустно найти, что это не допустимый синтаксис

var c=Controls.Where(x => x.ID=="Some ID").SingleOrDefault();

Однако от того, что я могу сказать, Controls действительно реализует IEnumerable интерфейс, который предоставляет такие методы, поэтому что дает? Почему это просто не работает? Я нашел достойному работу вокруг для этой проблемы, по крайней мере:

var list = (IEnumerable<Control>)Controls;
var this_item = list.Where(x => x.ID == "Some ID").SingleOrDefault();
38
задан Earlz 21 July 2010 в 18:17
поделиться

4 ответа

Нет, IEnumerable не имеет много методов расширения: IEnumerable does. Это два отдельных интерфейса, хотя IEnumerable расширяет IEnumerable.

Обычные способы преобразования в LINQ - это использование методов расширения Cast() и OfType() которые do расширяют негенерический интерфейс:

IEnumerable<TextBox> textBoxes = Controls.OfType<TextBox>();
IEnumerable<Control> controls = Controls.Cast<Control>();

Разница между ними в том, что OfType просто пропустит все элементы, не имеющие требуемого типа; Cast вместо этого выдаст исключение.

Как только вы получили ссылки на общий тип IEnumerable, становятся доступны все остальные методы LINQ.

74
ответ дан 27 November 2019 в 03:20
поделиться

Это происходит потому, что класс ControlCollection появился до появления дженериков; поэтому он реализует IEnumerable, но не IEnumerable.

К счастью, существует метод расширения LINQ для интерфейса IEnumerable, который позволяет генерировать IEnumerable через кастинг: Cast. Что означает, что вы всегда можете просто сделать это:

var c = Controls.Cast<Control>().Where(x => x.ID == "Some ID").SingleOrDefault();
9
ответ дан 27 November 2019 в 03:20
поделиться

В дополнение к ответам, предоставленным Джоном Скитом и Дэном Тао, вы можете использовать синтаксис выражения запроса, явно указав тип.

Control myControl = (from Control control in this.Controls
                    where control.ID == "Some ID"
                    select control).SingleOrDefault();
4
ответ дан 27 November 2019 в 03:20
поделиться

Linq utilized Generic Collections. ControlsCollection implements IEnumerable not IEnumberable

Если вы заметили, это не будет работать

((IEnumerable)page.Controls).Where(...

Однако, это работает

((IEnumerable<Control>)page.Controls).Where(...

Вы можете либо привести к Generic IEnumerable, либо обратиться к методу расширения, который это делает, например так:

 page.Controls.OfType<Control>().Where(c => c.ID == "Some ID").FirstOrDefault();
2
ответ дан 27 November 2019 в 03:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: