C# 为什么';控件集合不提供所有IEnumerable方法吗?

C# 为什么';控件集合不提供所有IEnumerable方法吗?,c#,asp.net,linq,extension-methods,ienumerable,C#,Asp.net,Linq,Extension Methods,Ienumerable,我不确定ASP.Net的ControlCollection是如何工作的,所以也许有人可以帮我解释一下 我最近发现了扩展方法和Linq的魔力。嗯,我很难过地发现这不是有效的语法 var c=Controls.Where(x => x.ID=="Some ID").SingleOrDefault(); 然而,从我所知,控件确实实现了提供此类方法的IEnumerable接口,那么给出了什么呢?为什么这不管用?我已经找到了解决这个问题的好办法,至少: var list = (IEnumerabl

我不确定ASP.Net的ControlCollection是如何工作的,所以也许有人可以帮我解释一下

我最近发现了扩展方法和Linq的魔力。嗯,我很难过地发现这不是有效的语法

var c=Controls.Where(x => x.ID=="Some ID").SingleOrDefault();
然而,从我所知,
控件
确实实现了提供此类方法的
IEnumerable
接口,那么给出了什么呢?为什么这不管用?我已经找到了解决这个问题的好办法,至少:

var list = (IEnumerable<Control>)Controls;
var this_item = list.Where(x => x.ID == "Some ID").SingleOrDefault();
var list=(IEnumerable)控件;
var this_item=list.Where(x=>x.ID==“Some ID”).SingleOrDefault();

不,
IEnumerable
没有很多扩展方法:
IEnumerable
有。它们是两个独立的接口,尽管
IEnumerable
扩展了
IEnumerable

正常的LINQ转换方法是使用扩展非通用接口的和扩展方法:

IEnumerable<TextBox> textBoxes = Controls.OfType<TextBox>();
IEnumerable<Control> controls = Controls.Cast<Control>();
IEnumerable textboxs=Controls.OfType();
IEnumerable controls=controls.Cast();
两者的区别在于类型的
只会跳过任何不属于所需类型的项目<代码>强制转换
将引发异常

一旦您获得了泛型
IEnumerable
类型的引用,所有其余的LINQ方法都可用。

这只是因为类出现在泛型之前;因此它实现了
IEnumerable
,但没有
IEnumerable

幸运的是,
IEnumerable
接口上确实存在一个LINQ扩展方法,允许您通过强制转换生成
IEnumerable
。这意味着您可以始终这样做:

var c = Controls.Cast<Control>().Where(x => x.ID == "Some ID").SingleOrDefault();
var c=Controls.Cast()。其中(x=>x.ID==“Some ID”).SingleOrDefault();

除了Jon Skeet和Dan Tao提供的答案之外,还可以通过显式提供类型来使用查询表达式语法

Control myControl = (from Control control in this.Controls
                    where control.ID == "Some ID"
                    select control).SingleOrDefault();

Linq利用了泛型集合。控件集合实现
IEnumerable
而不是
IEnumerable

如果您注意到这将不起作用

((IEnumerable)page.Controls).Where(...
然而,这是真的

((IEnumerable<Control>)page.Controls).Where(...
((IEnumerable)page.Controls)。其中(。。。
您可以强制转换为Generic
IEnumerable
,也可以访问这样做的扩展方法,如下所示:

 page.Controls.OfType<Control>().Where(c => c.ID == "Some ID").FirstOrDefault();
page.Controls.OfType()。其中(c=>c.ID==“Some ID”).FirstOrDefault();

您可以执行
list.SingleOrDefault(x=>x.ID==“Some ID”);
是否有原因没有更新它以实现
IEnumerable
?这不应该破坏向后兼容性。