AddComponent(字符串变量)调用函数

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

myScript.runCustomFunction();

这不起作用。我相信这是因为在编译时(而不是运行时),如果我不知道变量类型就不能转换变量类型。因此,我不能直接访问刚刚添加的组件。
gameItem类能够从另一个脚本拉取默认值,然后把它们放入dictionary entry里。基于库条目"functionScript","myScript",我需要把myScript附加到对象上,然后传递给它一些dictionary entry。
或者,可能非常低效,在myScript类上询问项目类的变量,这个我其实想避免的。

原文:Call a function on AddComponent( string variable )

阅读 5.2k
1 个回答

答案:
Josh
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,如果你不想使用动态,则可用一点映射来调用该方法

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

正如你所看到的,从基本类型继承或者实现接口会简单很多,如果你不怕困难,也可以用映射。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进