Как создать экземпляр UserControl-потомка?

Вот сценарий. У меня есть несколько UserControl, которые наследуются от MyBaseControl. Я хотел бы создать экземпляр UserControl на основе его имени. Например:

void foo(string NameOfControl) {
    MyBaseControl ctl = null;        
    ctl = CreateObject(NameOfControl);  // I am making stuff up here, 
                                        // CreateObject does not exist
}

Как создать экземпляр этого UserControl на основе его имени. У меня мог бы быть гигантский оператор switch, и это плохо пахнет. Все UserControls, включая их базовый класс, находятся в одном проекте и имеют одно и то же пространство имен.


person AngryHacker    schedule 23.11.2009    source источник


Ответы (2)


    void foo(string NameOfControl)
    {
        MyBaseControl ctl = null;
        ctl = (MyBaseControl) Assembly.GetExecutingAssembly().CreateInstance(typeof(MyBaseControl).Namespace + "." + NameOfControl);
    }

Выше предполагается, что каждый производный класс элемента управления является конструктором без параметров по умолчанию.

person logicnp    schedule 24.11.2009

Лучший способ сделать это - загрузить тип через отражение. Поскольку все они находятся в одной сборке / пространстве имен, вы можете это сделать. В противном случае вам придется загружать сборку отдельно. Кроме того, предполагается, что конструктор пустой.

MyBaseControl ctl = null;
ctl = (MyBaseControl) typeof(MyBaseControl).assembly.GetType(NameOfControl).GetConstructor(new Type[0]).Invoke(new object[0]);

Если конструктор не пустой, измените массивы типа / объекта.

person Erich    schedule 23.11.2009
comment
Не работает, я получаю ссылку на объект, не относящуюся к экземпляру объекта. - person AngryHacker; 24.11.2009
comment
Это правильное решение. Узнайте, какая часть выражения является нулевой, разбив ее на части. Assembly.GetType () - вероятный нуль, убедитесь, что вы также передаете имя пространства имен. - person Hans Passant; 24.11.2009
comment
Null Ref может произойти только в одном из двух мест: GetType или GetConstructor. Если ваша переменная NameOfControl неверна (требуется полное пространство имен), она не будет работать, или если у вас нет общедоступного пустого конструктора, она не будет работать. - person Erich; 24.11.2009