Selecting all the controls of a specific type, the (built in!) LINQ way
We probably all worked with dynamically generated controls on forms, ASP.NET pages or (user) controls. And I guess we've all written for-each statements to loop through the ControlCollection and filter out all the controls of a specific type, right? I wanted to do the same today, so I started by trying to use LINQ for this:
This, as you can see, generated a compile time error:
Could not find an implementation of the query pattern for source type 'System.Web.UI.ControlCollection'. 'Where' not found. Consider explicitly specifying the type of the range variable 'control'.
As the error states, this is easily solved by explicitly specifying the type of the control variable. Because a ControlCollection can contain so many types, it is not strange the compiler asks you to be a bit more precise on the type you will be querying. That looks something like this:
But when I added the System.Linq namespace to my using section, I saw an extra method on the ControlCollection, called OfType<>. This method is one of the extension methods that can be applied to a collection that has a non-parameterized type like a ControlCollection or an ArrayList, because OfType<> extends the type IEnumerable.
Another one of those nice 'native' Linq extension methods is the Cast<> method, which pretty much does the same but throws an exception if there are any objects in the collection that cannot be cast to the specified type. And yes, exceptions are sometimes wanted ;)
For more info on the OfType<> method, see: Enumerable.OfType<TResult> Generic Method
For more info on the Cast<> method, see: Enumerable.Cast<TResult> Generic Method