Type thistype = stringVar.GetType();
thistype myScript = gameObject.AddComponent(stringVar);
myScript.runCustomFunction();
这不起作用,我相信这是因为如果我在编译时不知道变量类型(而不是运行),我就无法转换为变量类型,因此我无法直接访问组件I刚补充。
我有一个gameItem类,它从另一个脚本中提取默认值,然后将它们放入字典中。根据字典条目“functionScript”,“myScript”,我需要将myScript附加到对象,然后传递一些字典条目。
或者,我可能效率非常低,并且在myScript类中询问item类的变量,我宁愿避免。
答案 0 :(得分:1)
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
那么您可以使用一点点反射到invoke that method。
//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
);
正如您所看到的,只是让所有类型都从某个基类继承或实现一个接口要容易得多,但如果您想以艰难的方式执行它,您当然可以使用反射:)