Ok, he aprovechado esta idea todo el día, y he llegado a la parte en la que admito que simplemente no sé. Es posible que lo que estoy haciendo sea estúpido y haya una mejor manera, pero aquí es donde mi pensamiento me ha traído.¿Cómo se puede convertir a un tipo usando el nombre del tipo como una cadena?
Estoy intentando utilizar un método genérico para cargar formas en WinForms:
protected void LoadForm<T>(ref T formToShow, bool autoLoaded) where T : FormWithWorker, new()
{
// Do some stuff
}
Las formas son cargados por un ToolStripMenuItem (ya sea a través de la selección del elemento o utilizando el elemento de menú Abrir Windows). Son de carga lenta, por lo que hay campos para los formularios dentro del padre MDI, pero son nulos hasta que se necesiten. Tengo un método común utilizado para ToolStripMenuItem_Click que maneja todos los clics de elemento de menú. El método no tiene una forma real de saber qué formulario se solicita, excepto que el nombre del ToolStripMenuItem coincide con un patrón elegido para los nombres de clase de formulario a los que corresponden. Entonces, usando el nombre del ToolStripMenuItem, puedo deducir el nombre del tipo de formulario que se solicita y el nombre del campo privado asignado para almacenar la referencia para ese formulario.
Usando eso, puedo usar una instrucción de cambio creciente/contratante con tipos de código fijo y cadena de coincidencias para llamar al método con el tipo específico establecido (indeseable), o puedo usar Reflection para obtener el campo y crear la instancia del tipo El problema para mí es que System.Activator.CreateInstance
proporciona un ObjectHandler que no se puede convertir a los tipos que necesito. Aquí hay un fragmento de lo que tengo hasta ahora:
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);
sé que el nombre de la cadena del tipo que va en los (????), pero en tiempo de compilación no sé el tipo, ya que cambia . He intentado varias formas de hacer funcionar este molde/instanciación, pero ninguno ha tenido éxito. Me gustaría mucho saber si es posible realizar dicho reparto sabiendo el tipo solo como una cadena. Intenté usar Type.GetType(string, string)
para realizar el reparto, pero al compilador no le gustó. Si alguien tiene una idea diferente sobre cómo cargar los formularios dinámicamente porque lo estoy haciendo de forma estúpida, házmelo saber.
hacer el objeto formToLoad y convertirlo a FormWithWorker en los puntos LoadForm y SetValue? – asawyer