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();
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.
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();
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();
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();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With