Как можно привести к типу, используя имя типа в виде строки?

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

Я пытаюсь использовать универсальный метод для загрузки форм в WinForms:

protected void LoadForm<T>(ref T formToShow, bool autoLoaded) where T : FormWithWorker, new()
{
    // Do some stuff
}

Формы загружаются с помощью ToolStripMenuItem (либо путем выбора элемента, либо с помощью пункта меню «Открыть Windows»). Они загружаются лениво, поэтому в родительском MDI есть поля для форм, но они остаются пустыми, пока не понадобятся. У меня есть общий метод, используемый для ToolStripMenuItem_Click, который обрабатывает все щелчки по пунктам меню. У метода нет реального способа узнать, для какой формы вызывается, за исключением того, что имя ToolStripMenuItem соответствует шаблону, выбранному для имен классов формы, которым они соответствуют. Итак, используя имя ToolStripMenuItem, я могу угадать имя типа запрашиваемой формы и имя частного поля, выделенного для хранения ссылки для этой формы.

Используя это, Я могу либо использовать растущий / сужающийся оператор switch с жестко закодированными типами и строковыми совпадениями для вызова метода с определенным набором типов (нежелательно), либо я могу использовать Reflection для получения поля и создания экземпляра типа. Проблема для меня в том, что System.Activator.CreateInstance предоставляет ObjectHandler, который не может быть приведен к нужным мне типам. Вот отрывок из того, что у меня есть на данный момент:

string formName = "_form" + ((ToolStripMenuItem)sender).Name.Replace("ToolStripMenuItem", "");
string formType = formName.Substring(1);

FieldInfo fi = this.GetType().GetField(formName, BindingFlags.NonPublic | BindingFlags.Instance);

FormWithWorker formToLoad = (FormWithWorker)fi.GetValue(this);
if (formToLoad == null)
{
    formToLoad = (????)System.Activator.CreateInstance("MyAssemblyName", formType);
}

this.LoadForm(ref formToLoad, false);
fi.SetValue(this, formToLoad);

Я знаю строковое имя типа, который используется для (????), но во время компиляции я не знаю тип, потому что он изменяется. Я пробовал несколько способов заставить это приведение / создание экземпляра работать, но ни один из них не увенчался успехом. Я очень хотел бы знать, возможно ли выполнить такое приведение, зная тип только как строку. Я пробовал использовать Type.GetType (string, string) для выполнения приведения, но компилятору это не понравилось. Если у кого-то есть другое представление о том, как динамически загружать формы, потому что я просто делаю это по глупости, сообщите мне об этом.

7
задан Joel Etherton 28 January 2011 в 19:10
поделиться