Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用类型名作为字符串强制转换为类型?_C#_Winforms_Reflection_Casting - Fatal编程技术网

C# 如何使用类型名作为字符串强制转换为类型?

C# 如何使用类型名作为字符串强制转换为类型?,c#,winforms,reflection,casting,C#,Winforms,Reflection,Casting,好吧,我一整天都在重复这个想法,我已经到了我承认我完全不知道的地步。有可能我所做的只是愚蠢,还有更好的方法,但这就是我的想法带给我的 我正在尝试使用通用方法在WinForms中加载表单: protected void LoadForm<T>(ref T formToShow, bool autoLoaded) where T : FormWithWorker, new() { // Do some stuff } 我知道(??)所用类型的字符串名称,但在编译时我不知道该类型

好吧,我一整天都在重复这个想法,我已经到了我承认我完全不知道的地步。有可能我所做的只是愚蠢,还有更好的方法,但这就是我的想法带给我的

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

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

我知道(??)所用类型的字符串名称,但在编译时我不知道该类型,因为它会更改。我已经尝试了很多方法来让这个cast/实例化工作,但都没有成功。我非常想知道,如果只知道类型是字符串,是否可以执行这样的强制转换。我尝试使用
Type.GetType(string,string)
执行强制转换,但编译器不喜欢它。如果有人对如何动态加载表单有不同的想法,因为我做得很愚蠢,请告诉我。

这个问题通常通过强制转换到所有潜在类型的公共基类或接口来解决


在C#4中,您还可以将其分配给
动态
变量,以保存返回值并对其调用任意方法。这些方法将是后期绑定的。但是,我更愿意尽可能地坚持前一种解决方案。

根据您所拥有的,
FormWithWorker
必须(至少)作为您正在实例化的类型的基类,因此您可以执行以下操作:

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

虽然公共接口是解决此问题的一种方法,但接口并不适用于所有场景。上面的决定是使用工厂模式(switch语句-具体的类选择)还是使用反射。有一个栈柱可以解决这个问题。我相信您可以直接将此应用于您的问题:


您最好使用一个
类型,并使用例如


将formToLoad对象转换为FormWithWorker,并在LoadForm和设置值点?向上投票。我用一个接口做了类似的事情,效果很好。我尝试了这个方法,但遇到的问题是,它最终分配的动态类型是基类,而不是实际的类,所以在调用SetValue方法时,它抛出了一个类型转换异常。@Joel,另一个答案指出,您应该使用返回对象本身的重载。显然,您使用的重载对于激活.NET远程处理对象很有用。今天早上我对这个主题有了新的想法,我无法让@Andras Vass的答案生效的原因是我在CreateInstance中使用了错误的名称空间/类型调用。一旦我意识到这个错误,他的想法就成功了。不过,我对你的答案做了+1处理,因为这对我来说很有意义。我尝试了这个方法,但由于
System.Activator.CreateInstance
方法返回ObjectHandler,我收到了一个强制转换错误。我刚刚读到@Andras Vass调用
Unwrap()
的想法,我下一步将尝试结合使用这两种方法。我记得有一次,这篇文章特别提到了
System.Activator.CreateInstance
上的
.Unwrap()
方法。它现在没有这样说,但应该这样说,因为我的问题的解决方案是用基类的类型声明私有字段,然后调用
CreateInstance(“namespace”,“type”).Unwrap()
。这创建了正确的类型并允许方法正确实例化。如果必须强制转换它,为什么这很有用?
FormWithWorker formToLoad = (FormWithWorker)fi.GetValue(this);
if (formToLoad == null)
{
    formToLoad = (FormWithWorker)System.Activator.CreateInstance("MyAssemblyName", formType);
}
FormWithWorker formToLoad = (FormWithWorker)fi.GetValue(this);
if (formToLoad == null)
{
    formToLoad =
      (FormWithWorker)System.Activator.CreateInstance(Type.GetType("MyNamespace.MyFormType"));
}