foreach变量的动态类型

时间:2009-10-23 20:47:32

标签: c# foreach

在下面的代码中,如何将变量类型传递给嵌套的foreach语句? getControls是一个递归函数,它返回一个控件列表(哇!)

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 个答案:

答案 0 :(得分:7)

foreach语句可以强制转换枚举变量:

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

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

只要枚举中所有的按钮属于MySpecialButton类型而不是从Button派生,这将有效。如果您不知道,那么您只能枚举MySpecialButton类型的按钮:

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

OfTypeCast的不同之处在于它过滤了枚举,而不是在对象属于无法转换为目标类型的类型时抛出异常。

答案 1 :(得分:4)

迭代变量需要与列表项类型兼容。

因此编译器只允许你编写

foreach(Control c in controls)

但在foreach块中,您可以使用类型转换来调用特定类型的方法:

{
    if (c is MyControlType)
        (c as MyControlType).StateCommon.Back.Color1 = Color.White;
}

答案 2 :(得分:1)

如果您只引用foreach中超类型(Control)上可用的值,则只需将其声明为Control。

如果你有类型特定的逻辑,你仍然需要将它声明为Control,但是然后找出你在每次迭代中处理的类型并使用强制转换和条件逻辑。

这样做的一种方法是将foreach的主体重构为一组方法(即Update(Button),Update(KryptonTextBox)),然后调用Update(c)。

答案 3 :(得分:1)

foreach变量需要匹配列表类型。

foreach(Control c in controls)

foreach(Object c in controls)

我猜测,因为您将类型列表传递给getControls,它只返回该类型的控件,但如果不是,则需要验证类型

if(t.IsAssignableFrom(c))

然后,您需要使用反射来设置属性。