Why doesn't the Controls collection provide all of the IEnumerable methods?

二次信任 提交于 2019-11-29 05:58:59

问题


I'm not for sure how the ControlCollection of ASP.Net works, so maybe someone can shed some light on this for me.

I recently discovered the magic that is extension methods and Linq. Well, I was very sad to find that this isn't valid syntax

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

However from what I can tell, Controls does implement the IEnumerable interface which provides such methods, so what gives? Why doesn't that just work? I have found a decent work around for this issue at least:

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

回答1:


No, IEnumerable doesn't have many extension methods on it: IEnumerable<T> does. They are two separate interfaces, although IEnumerable<T> extends IEnumerable.

The normal LINQ ways of converting are to use the Cast<T>() and OfType<T>() extension methods which do extend the nongeneric interface:

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

The difference between the two is that OfType will just skip any items which aren't of the required type; Cast will throw an exception instead.

Once you've got references to the generic IEnumerable<T> type, all the rest of the LINQ methods are available.




回答2:


This is just because the ControlCollection class came around before generics; so it implements IEnumerable but not IEnumerable<Control>.

Fortunately, there does exist a LINQ extension method on the IEnumerable interface that allows you to generate an IEnumerable<T> through casting: Cast<T>. Which means you can always just do this:

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



回答3:


In addition to the answers provided by Jon Skeet and Dan Tao, you can use query expression syntax by explicitly providing the type.

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



回答4:


Linq utilized Generic Collections. ControlsCollection implements IEnumerable not IEnumberable<T>

If you notice this will not work

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

However, this does

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

You can either cast to Generic IEnumerable<T> or access an extension method that does, like so:

 page.Controls.OfType<Control>().Where(c => c.ID == "Some ID").FirstOrDefault();


来源:https://stackoverflow.com/questions/3302435/why-doesnt-the-controls-collection-provide-all-of-the-ienumerable-methods

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!