[英]How can I invoke a method from a Type or its derived Types?
我正在尝试复制Unity 3D引擎的MonoBehaviour
。 我在Linux上使用monodevelop,大多数测试将在Windows中完成。
关于MonoBehavior.Start
更多信息可以在这里阅读。
我想在从MonoBehavior继承的所有类型上调用Start
方法。
这是我尝试过的:
class MonoBehaviour
{
static Type[] types = Assembly.GetExecutingAssembly().GetTypes();
public static void Main ()
{
foreach (Type type in types)
{
if (type.IsSubclassOf(typeof(MonoBehaviour)))
{
MethodInfo minfo = type.GetMethod ("Start");
mInfo.Invoke (type, null); // This throws
}
}
}
}
class example : MonoBehaviour
{
void Start()
{
// I want this to be run from MonoBehaviour
Console.WriteLine ("HelloWorld");
}
}
class example1 : MonoBehaviour
{
}
编辑完全重做此答案,因为现在我相信我知道您在问什么。
我将为您提供代码,使您可以调用程序集中Type的每个对象的Start。 但是,我不认为这是MonoBehavior的工作方式。 还有更多需要考虑的地方。 例如,应该首先调用Awake
,并且存在是否已启用脚本的条件。 另外,我不认为立即在所有对象上调用此方法,而可能仅在对象被创建/启动时才调用。 我没有Unity 3D经验,所以我对这些细节一无所知。 我仅依靠我从您的问题链接中看到的内容。
我添加了一些额外的绑定标志,以表明它可以找到各种范围的方法。 另外,在我的代码中,我明确地寻找没有参数的Start
方法。 可以根据您的需要和喜好进行修改。
using System;
using System.Reflection;
class Program
{
static void Main(string[] args)
{
Assembly asm = Assembly.GetExecutingAssembly();
Type[] types = asm.GetTypes();
foreach (var type in types)
{
if (type.IsSubclassOf(typeof(MonoBehavior)) || type.GetInterfaces().Contains(typeof(MonoBehavior)))
{
MethodInfo startMethod = type.GetMethod("Start", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { }, null);
if (startMethod != null)
{
ConstructorInfo ctor = type.GetConstructor(new Type[] { });
if (ctor != null)
{
object inst = ctor.Invoke(new object[] { });
startMethod.Invoke(inst, new object[] { });
}
}
}
}
}
}
interface MonoBehavior
{
}
class Example1 : MonoBehavior
{
static void Start()
{
Console.WriteLine("Example1 Start");
}
}
class Example2 : MonoBehavior
{
}
现在,如果您不喜欢创建对象,则可以将Start
静态,反射中的几行将进行如下调整:
MethodInfo startMethod = type.GetMethod("Start", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static, null, new Type[] { }, null);
if (startMethod != null)
{
startMethod.Invoke(null, new object[] { });
}
请注意,我不再需要创建实例,并且传递给Invoke
的第一个参数为null(始终对static
方法执行此操作)。
但是,阅读MonoBehaviour.Start
上的Unity3D文档并不会给我留下任何印象,首先是它打算以这种方式运行,更不用说静态了。 我认为应该在其他各种条件下创建MonoBehaviour
时运行它。 该模型不需要反射,但我建议构建一种工厂模型,在该模型中,您将根据对工厂对象的请求创建MonoBeaviour
对象-该对象将在返回实例之前调用适当的Awake
和Start
方法。
类型不是其自己的子类,这就是为什么您有三种类型,但只有两种与条件匹配的原因。 (如果那是问题。)此外,MonoBehaviour没有Start()方法,否则我很累;-)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.