3
Type thistype = stringVar.GetType();
thistype myScript = gameObject.AddComponent(stringVar);

myScript.runCustomFunction();

这不起作用,我相信这是因为如果我在编译时(而不是运行)不知道变量类型,我无法转换为变量类型,因此我无法直接访问我刚刚添加的组件。

我有一个 gameItem 类,它从另一个脚本中提取其默认值,然后将它们放入字典中。基于字典条目“functionScript”、“myScript”,我需要将 myScript 附加到对象,然后将一些字典条目传递给它。

或者,我可能真的效率低下,并在 myScript 类中向 item 类询问其变量,我宁愿避免这样做。

4

1 回答 1

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那么您可以使用一点反射来调用该方法

//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
);

正如您所看到的,让您的所有类型都从某个基类继承或实现一个接口要容易得多,但是如果您想以艰难的方式做到这一点,您当然可以使用反射:)

于 2013-07-31T12:05:31.460 回答