Динамическая типизация переменной foreach - PullRequest
0 голосов
/ 24 октября 2009

В следующем коде, как я могу передать тип переменной во вложенный оператор 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 ]

7 голосов
/ 24 октября 2009

Оператор 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 тем, что фильтрует перечисление, а не выдает исключение, когда объект имеет тип, который не может быть приведен к целевому типу.

4 голосов
/ 24 октября 2009

Итерационная переменная должна быть совместимого типа с типами элементов списка.

Таким образом, компилятор позволяет писать только

foreach(Control c in controls)

но внутри блока foreach вы можете использовать приведение типов для вызова методов определенного типа:

{
    if (c is MyControlType)
        (c as MyControlType).StateCommon.Back.Color1 = Color.White;
}
1 голос
/ 24 октября 2009

Переменная foreach должна соответствовать типу списка.

foreach(Control c in controls)

или

foreach(Object c in controls)

Я предполагаю, что, поскольку вы передаете список типов getControls, он возвращает только элементы управления этого типа, но если нет, вам потребуется проверить тип

if(t.IsAssignableFrom(c))

Затем вам нужно будет использовать отражение, чтобы установить свойства.

1 голос
/ 24 октября 2009

Если вы ссылаетесь только на значения, доступные в супертипе (Control) внутри foreach, просто объявите его как Control.

Если у вас есть логика для конкретного типа, вам все равно нужно объявить ее как Control, но затем выясните, с каким типом вы имеете дело в каждой итерации, и используйте приведение и условную логику.

Один из способов сделать это - преобразовать тело foreach в набор методов (например, Update (Кнопка), обновить (KryptonTextBox)) и просто вызвать обновление (с).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...