现在我能说的最简单的例子就是如下所示。
在Unity3D中有几种方法。 void Awake()
,void Start()
。
所以我尝试创建的是几个都包含方法void Start()
的类,我希望void Main()
方法动态调用所有这些启动方法。我不想输入Class test = new Class()
等
如果有人能指引我正确的方向,或者甚至给我一些很好的代码示例。
答案 0 :(得分:4)
因此,您可以循环遍历每个类型,并确定该类型是否具有名为Start
的方法,并且具有您需要的确切签名。也许更好的方法是创建一个接口并让所有类实现它。例如:
public interface IStartable
{
void Start();
}
public class SomeClass : IStartable
{
public void Start()
{
Console.WriteLine("Starting inside SomeClass");
}
}
现在,您可以遍历所有已加载的程序集并搜索IStartable
的实现,例如:
var instances = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(a => a.GetTypes())
.Where(t => t.IsClass && typeof(IStartable).IsAssignableFrom(t))
.Select(t => (IStartable)Activator.CreateInstance(t));
foreach (var instance in instances)
{
instance.Start();
}
这假设所有这些类都有一个公共的无参数构造函数。
这可行,但效率不高。如果您想稍微扩展一下,那么您可能希望查看其他选项,例如Managed Extensibility Framework。
为了使它在更多情况下更通用和有用,这里它包含在一个可以应用于任何类型的方法中:
public void RunOnAll<T>(Action<T> action)
{
var instances = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(a => a.GetTypes())
.Where(t => t.IsClass && typeof(T).IsAssignableFrom(t))
.Select(t => (T)Activator.CreateInstance(t));
foreach (var instance in instances)
{
action(instance);
}
}
所以现在你会这样称呼它:
RunOnAll<IStartable>(x => x.Start());
答案 1 :(得分:0)
我不会为您提供代码,但意思是做这样的事情:
abstract class
或interface
,其中所有您想要的类都来自Activator.CreateInstance
创建实例https://msdn.microsoft.com/en-us/library/wccyzw83(v=vs.110).aspx Invoke
https://www.dotnetperls.com/methodinfo-invoke MethodInfo
醇>
答案 2 :(得分:-4)
它并不完全清楚你要问的是什么,但是如果你想在运行时加载并创建类的内容,你所寻找的区域叫做反射:(https://docs.microsoft.com/en-us/dotnet/framework/reflection-and-codedom/reflection)。这允许.net有效地分析和获取有关其自己的代码库的信息。
在您的情况下,您将能够加载您感兴趣的所有类(基于其名称或其他规则),创建实例并调用start方法,而无需在编译时获得此信息时间。