我不确定ASP.Net的ControlCollection是如何工作的,所以也许有人可以为我阐明这一点。
我最近发现了扩展方法和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();
答案 0 :(得分:71)
不,IEnumerable
上没有很多扩展方法:IEnumerable<T>
。它们是两个独立的界面,但IEnumerable<T>
扩展IEnumerable
。
正常的LINQ转换方式是使用做扩展非通用接口的Cast<T>()
和OfType<T>()
扩展方法:
IEnumerable<TextBox> textBoxes = Controls.OfType<TextBox>();
IEnumerable<Control> controls = Controls.Cast<Control>();
两者之间的区别在于OfType
只会跳过任何不属于所需类型的项目; Cast
会抛出异常。
一旦您获得了通用IEnumerable<T>
类型的引用,所有其他LINQ方法都可用。
答案 1 :(得分:8)
这只是因为ControlCollection
课程在仿制药之前出现了;所以它实现了IEnumerable
但不是IEnumerable<Control>
。
幸运的是,IEnumerable
界面上确实存在一个LINQ扩展方法,允许您通过强制转换生成 IEnumerable<T>
:Cast<T>
。这意味着您可以随时执行此操作:
var c = Controls.Cast<Control>().Where(x => x.ID == "Some ID").SingleOrDefault();
答案 2 :(得分:4)
除了Jon Skeet和Dan Tao提供的答案之外,您还可以通过明确提供类型来使用查询表达式语法。
Control myControl = (from Control control in this.Controls
where control.ID == "Some ID"
select control).SingleOrDefault();
答案 3 :(得分:2)
Linq使用了Generic Collections。 ControlsCollection实现IEnumerable
而非IEnumberable<T>
如果您发现这不起作用
((IEnumerable)page.Controls).Where(...
然而,这确实
((IEnumerable<Control>)page.Controls).Where(...
你可以转换为Generic IEnumerable<T>
或访问扩展方法,如下所示:
page.Controls.OfType<Control>().Where(c => c.ID == "Some ID").FirstOrDefault();