tags:

views:

250

answers:

4

In the following code, How can I pass the type of variable to the nested foreach statement? getControls is a recursive function that returns a list of controls (wow!)

getControls(String type, Control donde)  

var tipos = new List<Type>() { typeof(Button), typeof(KryptonTextBox) };

foreach (Type t in tipos)
{
  List<Control> controls = getControls(t.ToString(), this);
  foreach (***** c in controls)
  {
    c.StateCommon.Back.Color1 = Color.White;
  }    
}
+4  A: 

The iterating variable needs to be of a compatible type to the list item types.

Thus the compiler only allows you to write

foreach(Control c in controls)

but inside the foreach block, you can use type casts to call methods of a specific type:

{
    if (c is MyControlType)
        (c as MyControlType).StateCommon.Back.Color1 = Color.White;
}
devio
-1: Other that the fact that you are syntactically allowed to put an `is`/`as` inside the block, this is simply wrong. First, the compatibility of the foreach variable can include up, down, or interface casts. Second, when you do use `is`/`as`, you should use `as` followed by a null check instead.
280Z28
+1  A: 

If you only reference values available on the supertype (Control) inside the foreach, then just declare it as Control.

If you have type-specific logic, you'll still need to declare it as Control, but then figure out which type you're dealing with in each iteration and use casts and conditional logic.

One way to do that is to refactor the body of the foreach into a set of methods (i.e. Update(Button), Update(KryptonTextBox)) and just call Update(c).

technophile
+7  A: 

The foreach statement can cast the enumeration variable:

IEnumerable objects = ...;
foreach (AnyTypeHere i in objects)
    ...

IEnumerable<Button> buttons = ...;
foreach (MySpecialButton button in buttons)
    ...

This will work as long as all of the buttons in the enumeration are of type MySpecialButton than derives from Button. If you don't know that, then you can enumerate over only the buttons of type MySpecialButton like this:

IEnumerable<Button> buttons = ...;
foreach (MySpecialButton button in buttons.OfType<MySpecialButton>())
    ...

OfType differs from Cast in that it filters the enumeration rather than throwing an exception when an object is of a type that cannot be cast to the target type.

280Z28
This is a good way of doing it. The OfType<T>() extension method is handy for lists of differing types.
Jamie Penney
+1  A: 

The foreach variable needs to match the list type.

foreach(Control c in controls)

or

foreach(Object c in controls)

I am guessing that since you pass in the list of types to getControls, that it only returns controls of that type, but if not you will need to validate the type

if(t.IsAssignableFrom(c))

You would then need to use reflection to set the properties.

Mike J