5

For example. Lets say we have a stackpanel on a form. Its full of both Grids and Labels. I want to loop through all the Grids and do some operation on them but leave the Lables intact. At the moment I am doing it this way.

foreach(UIElement element in m_stacker.Children)
{
    Grid block = element as Grid;
    if(block != null)
    {
      //apply changes here
    }
}

So i'm using the fact that "as" returns null if it cannot cast into the required type. Is this an ok thing to do or is there a better solution to this problem?

DrLazer
  • 2,805
  • 3
  • 41
  • 52

4 Answers4

13

What about OfType()?

foreach( var grid  in m_stacker.Children.OfType<Grid>() ) { ... }

This will loop only over the children of type Grid, so no need to cast or check the type at all.

tanascius
  • 53,078
  • 22
  • 114
  • 136
  • 3
    In fact, `OfType()` is doing internally exactly the same. ;-) – Oliver May 20 '10 at 11:36
  • 3
    @Oliver: but the code looks more readably and is shorter this way. – tanascius May 20 '10 at 11:38
  • 1
    `OfType` is a good way to filter out elements of a type in a collection. However, if you want to do different things with different objects in a single collection (`var g = o as Grid; if (g != null) { /* do this */ } else { var c = o as Canvas; if (c != null) { /* do that */ } }`), you'll have to iterate the collection a few times with `OfType` -- and when you have a single object, rather than a collection, it's not a choice. – Mehrdad Afshari May 20 '10 at 11:43
  • @Mehrdad: that is correct, thanks for pointing it out. But for this question the OP wants to get items of *one type* - and then `OfType` is appropriate. – tanascius May 20 '10 at 11:49
  • Definitely. Just wanted to point out that `OfType` is not a *replacement* for `as`. It's kind of a replacement for a `foreach` **and** `as`. – Mehrdad Afshari May 20 '10 at 11:51
8

Yes, it's the right way to do it (considering "applying changes" will need to use the cast result).

However, if you are not going to use the cast return value, you can simply use is.

Using is and then casting again with the cast operator (parenthesis) is frowned upon.

Community
  • 1
  • 1
Mehrdad Afshari
  • 414,610
  • 91
  • 852
  • 789
2

It will work fine. What you can do is however just use "is".

foreach(UIElement element in m_stacker.Children)
{
    if(element is Grid)
    {
      //apply changes here
    }
}
sovanesyan
  • 1,098
  • 1
  • 8
  • 15
2

If you are going to use block as a Grid then this is exactly the right way to code it.

Checking using is (to my mind) produces less readable code as illustrated in the following two bad examples:

if (element is Grid)
{
    Grid block = element as Grid;
    // Do stuff
}

if (element is Grid)
{
    Grid block = (Grid)element;
    // Do stuff
}

Don't do either of these.

You're saying if element is a grid then cast it.

ChrisF
  • 134,786
  • 31
  • 255
  • 325