tipagem dinâmica da variável foreach
Pergunta
No código a seguir, Como eu posso passar o tipo de variável para a instrução foreach aninhada? getControls é uma função recursiva que retorna uma lista de controles (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;
}
}
Solução
As necessidades variáveis ??iteração a ser de um tipo compatível com os tipos de item de lista.
Assim, o compilador só lhe permite escrever
foreach(Control c in controls)
mas dentro do bloco foreach, você pode usar moldes tipo para chamar métodos de um tipo específico:
{
if (c is MyControlType)
(c as MyControlType).StateCommon.Back.Color1 = Color.White;
}
Outras dicas
A declaração foreach
pode converter a variável de enumeração:
IEnumerable objects = ...;
foreach (AnyTypeHere i in objects)
...
IEnumerable<Button> buttons = ...;
foreach (MySpecialButton button in buttons)
...
Isto irá funcionar, desde que todas dos botões na enumeração são do tipo MySpecialButton
que deriva de Button
. Se você não sabe isso, então você pode enumerar sobre apenas os botões do tipo MySpecialButton
assim:
IEnumerable<Button> buttons = ...;
foreach (MySpecialButton button in buttons.OfType<MySpecialButton>())
...
difere de OfType
Cast
em que filtra a enumeração em vez de gerar uma excepção, quando um objecto é de um tipo que não pode ser convertido para o tipo de alvo.
Se você apenas valores de referência disponíveis no supertipo (Control) dentro do foreach, em seguida, basta declará-lo como controle.
Se você tem lógica específica do tipo, você ainda precisa declará-lo como controle, mas, em seguida, descobrir que tipo você está lidando com em cada iteração e usar moldes e lógica condicional.
Uma maneira de fazer isso é refatorar o corpo do foreach em um conjunto de métodos (ou seja Update (Button), Update (KryptonTextBox)) e apenas chamar Update (c).
As necessidades variáveis ??foreach para coincidir com o tipo de lista.
foreach(Control c in controls)
ou
foreach(Object c in controls)
Eu estou supondo que desde que você passar na lista de tipos de getControls, que só retorna controles desse tipo, mas se não você terá que validar o tipo
if(t.IsAssignableFrom(c))
Você, então, necessidade de usar a reflexão para definir as propriedades.