好的,我整天都在想这个主意,现在已经达到了我承认自己完全不知道的那部分。我正在做的事情可能只是愚蠢的,并且有更好的方法,但这就是我的思想带给我的地方。

我正在尝试使用通用方法在WinForms中加载表单:

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

表单由ToolStripMenuItem加载(通过选择该项或使用“打开Windows”菜单项)。它们是延迟加载的,因此MDI父级中有表单的字段,但是在需要它们之前它们为空。我有一个用于ToolStripMenuItem_Click的通用方法,该方法可以处理所有菜单项的单击。该方法没有知道要调用哪种表单的实际方法,只是ToolStripMenuItem的名称与为其对应的表单类名称选择的模式匹配。因此,使用ToolStripMenuItem的名称,我可以分辨出所请求的表单类型的名称以及分配用于存储该表单引用的私有(private)字段的名称。

使用它,我可以使用带有硬编码类型和字符串匹配的增长/收缩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)执行转换,但编译器不喜欢它。如果有人因为我只是在愚蠢地做而对如何动态加载表单有不同的想法,请告诉我。

最佳答案

使用带有Typeother overload并使用例如 Type.GetType(string)

FormWithWorker formToLoad = (FormWithWorker)fi.GetValue(this);
if (formToLoad == null)
{
    formToLoad =
      (FormWithWorker)System.Activator.CreateInstance(Type.GetType("MyNamespace.MyFormType"));
}

关于c# - 如何使用类型名称作为字符串将其转换为类型?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4832087/

10-14 21:17
查看更多