我正试图从字符串中获取类类型。我觉得我可能对此要走很长的路,但这是我迄今为止的代码:
System.Reflection.MethodInfo method = typeof(MyClass).GetMethod("MyFunc");
string myInterfaceId = "ITest";
Type myType = _type; // This is a WPF App that ultimately calls this process
// Debugger shows that _is correctly populated
AssemblyName an = new AssemblyName(myType.AssemblyQualifiedName); // Error here
Assembly a = Assembly.Load(an);
System.Reflection.MethodInfo generic = method.MakeGenericMethod(
a.GetType(myInterfaceId))
我得到的错误是:
A first chance exception of type 'System.IO.FileLoadException' occurred in mscorlib.dll
所以,在程序集出错的时候,它已经在内存中了。是否不能使用反射加载内存中已有的程序集?有没有一种方法可以在不使用Assembly.Load(...
的情况下使用反射来加载它?
编辑:
多亏了@stakx的建议,我终于想出了这个:
var meInterfaceType = myType.GetTypeInfo().Assembly.DefinedTypes.FirstOrDefault(k => k.Name == myInterfaceId)
假设您的项目没有引用包含ITest
的程序集,获得等效于typeof(ITest)
的Type
对象的最简单方法可能是通过静态Type.GetType
方法:
// you need to specify the assembly-qualified name of your type parameter type:
var t = Type.GetType("FooNamespace.ITest, FooAssembly, Version=…, PublicKeyToken=…");
(如果您在项目中引用该程序集,只需设置t = typeof(FooNamespace.ITest)
即可。)
然后继续关闭您的通用方法:
var openMethod = typeof(MyClass).GetMethod("MyFunc"); // as before
var closedMethod = openMethod.MakeGenericMethod(t);
您可以获得如下类型:
var type = Type.GetType("MyString");
然后使用activator获取您的实例:
Activator.CreateInstance(type);
使用AssemblyQualifiedName是最愚蠢的字符串,但如果您的类在执行程序集、命名空间中。ClassName可以正常工作。
var type = Type.GetType("AssemblyQualifiedNameOfTheClass or namespace.ClassName");
var thing = (MyClass)Activator.CreateInstance(type);
从这一点来看,您可以像使用"namespace.ClassName"的实例一样使用"thing"。