var typeName = $"Drv{id}.Fonte";
var type = Type.GetType(typeName);
var myObject = Activator.CreateInstance(type);
Drv {id}是我的命名空间,Fonte是类名。
为什么'type'始终为null?
当我打电话给第三行时,我明白了:
System.ArgumentNullException:'值不能为空。'
答案 0 :(得分:2)
我将详细阐述实际部分。
正如其他人所说,你需要装配合格的名字。
为什么?那么看看Type.GetType(string typeName)
方法的评论。
参数:
// typeName:
//要获取的类型的程序集限定名称。请参见System.Type.AssemblyQualifiedName。// 如果类型在当前正在执行的程序集 或Mscorlib.dll中,则提供由其名称空间限定的类型名称就足够了。
请注意,只有 if 类型在当前正在执行的程序集中才足以像你一样调用它。
我在另一个项目中有一个类,我的主项目就像你一样。
using System.Reflection;
namespace Test2
{
public class Class1
{
public string CallMe()
{
return Assembly.GetExecutingAssembly().FullName;
}
}
}
然后我这样称呼它:
using System;
using System.Reflection;
using Test2;
namespace NetCore2._0
{
class Program
{
static void Main(string[] args)
{
var typeName = typeof(Test2.Class1).AssemblyQualifiedName;
var type = Type.GetType(typeName);
Console.WriteLine(Assembly.GetExecutingAssembly().FullName);
var myObject = Activator.CreateInstance(type) as Class1;
Console.WriteLine(myObject.CallMe());
}
}
}
我希望你能看到差异在哪里以及为什么你现在需要提供合格的名字。
答案 1 :(得分:1)
您需要Assembly qualified name。正如MSDN所述。
示例(来自MSDN链接):
TopNamespace.SubNameSpace.ContainingClass + NestedClass,MyAssembly程序
答案 2 :(得分:1)
用于实例化类型的字符串格式错误。
来自Type.GetType(String)
的文档:
typeName:String
要获取的类型的程序集限定名称。看到 AssemblyQualifiedName。如果类型在当前正在执行 汇编或在Mscorlib.dll中,提供类型名称就足够了 由其命名空间限定。
来自AssemblyQualifiedName
的文档:
类型的程序集限定名称由类型名称组成, 包括其命名空间,后跟逗号,后跟显示 程序集的名称。获得组件的显示名称 使用Assembly.FullName属性。
例如,类的程序集限定名称可能如下所示 这样:
TopNamespace.SubNameSpace.ContainingClass + NestedClass,MyAssembly, Version = 1.3.0.0,Culture = neutral,PublicKeyToken = b17a5c561934e089
答案 3 :(得分:1)
我最近写了这段代码。我需要在运行时实例化一个对象,就像你一样,但遇到了类的位置的几个问题(不同的程序集,作为vshost运行,作为IISExpress运行)。
这是一个非常通用的场景,因此对您的需求可能有点过分......
private static Type GetType(string typeName)
{
// check executing assembly
var type = Assembly
.GetExecutingAssembly()
.GetTypes()
.FirstOrDefault(x => x.FullName == typeName);
// if not found check referenced assemblies
if (type == null)
{
type = Assembly
.GetExecutingAssembly()
.GetReferencedAssemblies()
.Select(Assembly.Load)
.SelectMany(x => x.GetTypes())
.FirstOrDefault(x => x.FullName == typeName);
}
// if still not found check all suitably named assemblies in executing folder
if (type == null)
{
var files = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "*.dll");
if (files.Length == 0)
{
files = Directory.GetFiles(AppDomain.CurrentDomain.RelativeSearchPath, "*.dll");
}
files.ToList().ForEach(filename =>
{
if (type == null)
{
var assembly = Assembly.LoadFile(filename);
var castableAssembly = AppDomain.CurrentDomain.Load(assembly.GetName());
type = castableAssembly.GetTypes().FirstOrDefault(x => x.FullName == typeName);
}
});
}
return type;
}
这将返回null或可以与Activator.CreateInstance()
一起使用的类型,并且您知道它可以访问。在您的情况下,将您的代码更改为...
var typeName = $"Drv{id}.Fonte";
var type = GetType(typeName); // using the above method
var myObject = Activator.CreateInstance(type);
这不是性能友好的代码,但除非您经常这样做,或者您的工作目录有大量的程序集,否则您不必担心它。如果您正在做很多事情或者您有大量的装配,那么您应该重新考虑整体设计。