tags:

views:

79

answers:

1

Referring to my question on filtering ('constraining') types in a foreach loop, I am trying the first method in Charlie Flowers's answer, using the .Where method on the collection, but the compiler can't find .Where on the System.Web.UI.ControlCollection class. This is derived from IEnumerable, so what's the problem here?

foreach (var control in Controls.Where(i => i.GetType() == typeof(TextBox)))
+4  A: 

First, ensure you have using System.Linq; at the top of the file.

If you have a collection that implements IEnumerable but not IEnumerable<T>, but you know the objects are all of a given type (such as Control), then you can use the Cast<T> LINQ extension method:

foreach (var control in Controls.Cast<Control>()
        .Where(i => i.GetType() == typeof(TextBox))) {...}

However, given your Where clause, it might be more prudent, in this case, to use the OfType<T> method, which only returns those of a given type (Cast<T> throws an exception if anything is wrong):

foreach (var control in Controls.OfType<TextBox>()) {...}

The slight difference between this and your version is that the above will return subclasses of TextBox, where-as your GetType() == typeof(TextBox) version won't.

Basically, most of the LINQ extension methods are defined only for IEnumerable<T> / IQueryable<T>, not IEnumerable/IQueryable.

Marc Gravell
Thanks. I was actually looking at using 'where' in an example, to differentiate from OfType, to get exact types only, not all assignable types. The Cast<T> works well.
ProfK