Динамическая типизация переменной 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;
}
}
Решение
Итерационная переменная должна быть совместимого типа с типами элементов списка.
Таким образом, компилятор позволяет писать только
foreach(Control c in controls)
но внутри блока foreach вы можете использовать приведение типов для вызова методов определенного типа:
{
if (c is MyControlType)
(c as MyControlType).StateCommon.Back.Color1 = Color.White;
}
Другие советы
Оператор 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
тем, что фильтрует перечисление, а не выдает исключение, когда объект имеет тип, который не может быть приведен к целевому типу. р>
Если вы ссылаетесь только на значения, доступные в супертипе (Control) внутри foreach, просто объявите его как Control.
Если у вас есть логика для конкретного типа, вам все равно нужно объявить ее как Control, но затем выяснить, с каким типом вы имеете дело в каждой итерации, и использовать приведение и условную логику.
Один из способов сделать это состоит в том, чтобы преобразовать тело foreach в набор методов (то есть Update (Button), Update (KryptonTextBox)) и просто вызвать Update (c).
Переменная foreach должна соответствовать типу list.
foreach(Control c in controls)
или
foreach(Object c in controls)
Я предполагаю, что, поскольку вы передаете список типов в getControls, он возвращает элементы управления только этого типа, но если нет, вам нужно будет проверить тип
if(t.IsAssignableFrom(c))
Затем вам нужно будет использовать отражение для установки свойств.