System.Type
是一个实际类型,与System.Int32
, 或非常相似System.Guid
。您不能在代码中使用变量作为静态标识符,因为编译器不知道该类型是什么。
我认为您要做的是根据其名称构造一个具体类型。
您可以使用Activator.CreateInstance来执行此操作,只要您知道类型名称和程序集名称。
var typeName = "MyType";
var myType = Activator.CreateInstance("MyAssembly", typeName);
您还可以使用dynamic
关键字让 DLR 为您处理繁重的工作。
dynamic myType = Activator.CreateInstance("MyAssembly", typeName);
myType.runCustomFunction();
如果你的类型继承自一个通用的基类型,或者实现了一个接口,那么你可以将它转换为那个类型并调用你的方法。
//Safe cast as base type
var myType = Activator.CreateInstance("MyAssembly", typeName) as BaseType;
//Or safe cast as interface
var myType = Activator.CreateInstance("MyAssembly", typeName) as IMyType;
但是,如果您的类型不是从已知类型继承的,但您知道它们都有一个被调用的方法runCustomFunction
并且您不想使用,dynamic
那么您可以使用一点反射来调用该方法。
//Create the System.Type using assembly qualified name
var typeName = "MyType";
var assemblyQualifiedName = String.Format("MyAssembly.{0}", typeName);
var myType = Type.GetType(assemblyQualifiedName);
//Call activator overload, but `instance` is a System.Object
var instance = Activator.CreateInstance(myType);
//Use reflection to invoke the method
myType.InvokeMember(
"runCustomFunction", //member name
BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static,
null, //default binder
instance, //actual instance to invoke method on
null //no arguments so we use null
);
正如您所看到的,让您的所有类型都从某个基类继承或实现一个接口要容易得多,但是如果您想以艰难的方式做到这一点,您当然可以使用反射:)