如何按名称执行静态方法

时间:2019-07-16 12:09:41

标签: c# xml reflection static

我有一个具有这样的类名称的XML文件:

<ActiveMonitorsList>
        <MonitorName>CertificatesMonitor</MonitorName>
        <MonitorName>ServicesMonitor</MonitorName>
        <MonitorName>LogsMonitor</MonitorName>
        <MonitorName>DBMonitor</MonitorName>
</ActiveMonitorsList>

每个此类都包含一个方法:bool SingleCheck();

我想对该XML文件中的每个类执行此bool SingleCheck()方法。

最好的方法是什么?

这是我到目前为止所拥有的-它不起作用:

foreach (string monitorName in monitorsList)
{
    Type thisType = GetType();
    MethodInfo singleMonitorMethod = thisType.GetMethod("{monitorName}.SingleCheck");
    bool methodResult = singleMonitorMethod.Invoke(...);
}
  • 代替(...)-不知道在这里放什么,但我想得到 方法的结果(总是布尔)。
  • 我想通过参数传递的所有这些方法都是静态的。
  • 我想代表,Action或Func <>必须进入这里...

非常感谢您!

编辑:XML中的每个名称都指向一个单独的类。每个类都有相同的命名方法:public static bool SingleCheck()。 我想做的是:

  • 获取所有监视器名称(类名称将相同)
  • 在每个内部调用一个方法(每个类中的名称相同) 该列表中显示的课程。

编辑-已解决问题:

当我第一次创建项目时,我为所有监视器都包括了单独的文件夹。然后我改变了主意,删除了该文件夹,并手动将“相同文件”添加到了解决方案中。这样,这些文件仍然具有“ using <namespace>.Monitors” ... 这就是为什么我无法列出这些类,而Types仍为null的原因...

感谢所有建议! ;)

2 个答案:

答案 0 :(得分:2)

我建议对方法Invoke进行重载,它需要您提供一个对象(调用实例)和该方法的一组输入参数。

由于它是静态方法,因此您可以平静地传递null作为第一个参数,并且由于您的方法没有任何参数,因此您可以再次平静地传递null作为第二个值。不要忘记将object强制转换为相应的返回类型。就您而言,bool

bool methodResult = (bool)singleMonitorMethod.Invoke(null, null);

要获取正确的Type,您实际上需要知道名称空间!所以看起来像这样:

foreach (string monitorName in monitorsList)
{
    string typeName = $"{yourNameSpace}.{monitorName}";
    Type thisType = Type.GetType(typeName);
    MethodInfo singleMonitorMethod = thisType.GetMethod("SingleCheck");
    bool methodResult = (bool)singleMonitorMethod.Invoke(null, null);
}

如果循环在同一个命名空间中,那么它也应该起作用:

Type thisType = Type.GetType($"{GetType().Namespace}.{monitorName}");

答案 1 :(得分:1)

thisType.GetMethod("{monitorName}.SingleCheck")无法正常工作有两个原因。 1)您忘记了字符串插值$符号,因此正在搜索一个名为“ {monitorName} .SingleCheck”的方法,该方法显然不存在这样的名称。 2)您需要提供包含方法的类型,而不是thisType

Invoke必须以实例作为第一个参数来调用-静态方法为null-方法参数为对象数组。

假定监视器类与当前类型位于同一程序集中,则需要执行以下操作:

foreach (string monitorName in monitorsList)
{
  Type monitorType = GetType().Assembly.GetExportedTypes().Single(x => x.Name == monitorName);
  MethodInfo singleMonitorMethod = monitorType.GetMethod("SingleCheck");
  bool methodResult = (bool)singleMonitorMethod.Invoke(null, Array.Empty<object>());
}

相对于new object[0]new object[] { },我更喜欢Array.Empty,因为它不会每次都创建一个新对象。

已编辑:根据Mong Zhu的评论GetType(monitorName)确实需要标准名称来更改类型发现。