Использование C # для рекурсивного получения коллекции элементов управления из коллекции элементов управления

2

В настоящее время я пытаюсь извлечь коллекцию динамически созданных элементов управления (флажки и выпадающие списки) из рекурсивной коллекции управления (ретранслятора). Это код, который я использую.

private void GetControlList<T>(ControlCollection controlCollection, ref List<T> resultCollection)
{
    foreach (Control control in controlCollection)
    {
        if (control.GetType() == typeof(T))
            resultCollection.Add((T)control);

        if (control.HasControls())
            GetControlList(controlCollection, ref resultCollection);
    }
}

У меня возникают проблемы со следующей строкой:

resultCollection.Add((T)control);

Я получаю ошибку...

Cannot convert type 'System.Web.UI.Control' to 'T'

Любые идеи?

  • 0
    Вам действительно нужны дженерики здесь? Все элементы управления получены из System.Web.UI.Control
  • 1
    ref не требуется в параметре списка btw.
Показать ещё 3 комментария
Теги:

2 ответа

6
Лучший ответ

Проблема:

Так как T может быть reference type или value type, компилятору нужна дополнительная информация.

Вы не можете конвертировать и Integer в Control.

Решение:

Чтобы исправить это, добавьте where T : Control или where T : class (более общее) ограничение, чтобы указать, что T всегда будет ссылочным типом.

Пример:

private void GetControlList<T>(ControlCollection controlCollection, ref List<T> resultCollection)
where T : Control
{
    foreach (Control control in controlCollection)
    {
        //if (control.GetType() == typeof(T))
        if (control is T) // This is cleaner
            resultCollection.Add((T)control);

        if (control.HasControls())
            GetControlList(control.Controls, ref resultCollection);
    }
}
  • Вам также не нужно ref ключевое слово. Поскольку List является ссылочным типом, эта ссылка будет передана.
  • 1
    Как @code, упомянутый в другом комментарии, последняя строка должна быть GetControlList (control.Controls, ref resultCollection);
  • 0
    @s_hewitt: Спасибо за указание на это.
3

Измените его на

var c = control as T;
if (c != null)
    resultCollection.Add(c);

Это будет быстрее, чем ваша треска, поскольку она не вызывает GetType().
Обратите внимание, что он также добавит элементы управления, наследующие T.

Вам также необходимо ограничить параметр типа, добавив where T : Control.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню