2009-10-23 48 views
-1

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

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; 
    }  
} 
+0

恩......“Button”没有“StateCommon”成员。您将无法在返回的按钮上运行该代码。 – 2009-10-23 20:54:03

+0

@Joel你不知道Button的实际类型是什么,所以很难说明确的。 – technophile 2009-10-23 20:56:07

+0

我稍后再尝试... – Luiscencio 2009-10-23 20:58:56

回答

4

的迭代变量必须是兼容类型的列表项类型。

因此编译器只允许你写

foreach(Control c in controls) 

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

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

-1:其他的,你在句法上允许在块内部放置一个'is'''as',这是完全错误的。首先,foreach变量的兼容性可以包括向上,向下或接口强制转换。其次,当你使用'is''''as'时,你应该使用'as',然后用空检查代替。 – 2009-10-24 14:37:05

1

如果你只是参考值可用于foreach内的超类型(Control),然后将其声明为Control。

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

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

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>()) 
    ... 

OfType不同于Cast,它过滤枚举,而不是当一个对象是其抛出异常不能转换为目标类型的类型。

+1

这是一个很好的做法。 OfType ()扩展方法适用于不同类型的列表。 – 2009-10-26 20:51:11

1

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

foreach(Control c in controls) 

foreach(Object c in controls) 

我猜测,因为你传递的类型的GetControls列表,它只返回该类型的控制,但如果没有,你将需要验证的类型

if(t.IsAssignableFrom(c)) 

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