如何在所有类中调用方法?

时间:2017-08-23 12:54:49

标签: c# unity3d

现在我能说的最简单的例子就是如下所示。

在Unity3D中有几种方法。 void Awake()void Start()

所以我尝试创建的是几个都包含方法void Start()的类,我希望void Main()方法动态调用所有这些启动方法。我不想输入Class test = new Class()

如果有人能指引我正确的方向,或者甚至给我一些很好的代码示例。

3 个答案:

答案 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)

我不会为您提供代码,但意思是做这样的事情:

  1. 创建一个abstract classinterface,其中所有您想要的类都来自
  2. 扫描程序集以查找从该类继承的类https://stackoverflow.com/a/17680332/1514875
  3. 您现在有一个班级列表
  4. 循环使用Activator.CreateInstance创建实例https://msdn.microsoft.com/en-us/library/wccyzw83(v=vs.110).aspx
  5. 使用反射获取方法https://msdn.microsoft.com/en-us/library/system.type.getmethod(v=vs.110).aspx
  6. 在返回的Invoke https://www.dotnetperls.com/methodinfo-invoke
  7. 上使用您创建的实例调用MethodInfo

答案 2 :(得分:-4)

它并不完全清楚你要问的是什么,但是如果你想在运行时加载并创建类的内容,你所寻找的区域叫做反射:(https://docs.microsoft.com/en-us/dotnet/framework/reflection-and-codedom/reflection)。这允许.net有效地分析和获取有关其自己的代码库的信息。

在您的情况下,您将能够加载您感兴趣的所有类(基于其名称或其他规则),创建实例并调用start方法,而无需在编译时获得此信息时间。