【问题标题】:How to execute static methods by name如何按名称执行静态方法
【发布时间】:2019-11-25 04:06:57
【问题描述】:

我有一个类名如下的 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(...);
}
  • 代替 (...) - 不知道该放什么,但我想得到 方法的结果(它总是布尔值)。
  • 我想作为参数传递的所有方法都是静态的。
  • 我猜委托、Actions 或 Func 必须进入这里...

非常感谢您!

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

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

编辑 - 问题已解决:

当我第一次创建我的项目时,我为所有监视器包含了单独的文件夹。然后我改变了主意,删除了这个文件夹并手动将 SAME FILES 添加到我的解决方案中。这样 - 那些文件仍然有“using &lt;namespace&gt;.Monitors”... 这就是为什么我无法列出这些类并且类型仍然为空的原因......

感谢所有建议! ;)

【问题讨论】:

  • 你在哪里执行 foreach 循环? Type 你对GetType() 的电话有什么期待?
  • @Selvin 这并不是真正的重复,因为这里不仅要为静态方法调用 MethodInfo,还要在类型中查找方法。
  • 我正在寻找一个 CLASS 名称,XML 包含 CLASSES 名称。在每个公共类中都有一个名为 SingleCheck() 的方法。这个方法是静态的。
  • 编辑了这个问题,它很复杂,所以我不确定这是否可以理解。

标签: c# xml reflection static


【解决方案1】:

我建议采用 Invoke 方法的这种重载它需要一个对象(调用实例)和一组来自您的方法的输入参数。

因为它是一个静态方法,你可以冷静地传递null作为第一个参数,因为你的方法没有任何参数,你可以冷静地传递null作为第二个值。不要忘记将object 转换为相应的返回类型。在你的情况下bool

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

要获得正确的类型,您实际上需要知道命名空间!所以这看起来像这样:

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}");

【讨论】:

  • 我有单独的公共类,每个公共类中都有相同的方法,称为“SingleCheck”。我不能直接使用我的命名空间名称。
  • @KamilTurowski "我不能直接使用我的命名空间名称" 是不同命名空间中的类吗?
  • 嗯,它们都在同一个命名空间中。虽然 - 您建议 {yourNameSpace}.SingleCheck -> 它没有返回类名 - 我需要的那个。
  • @KamilTurowski 该死的,这是一个大的复制粘贴错字。对不起,我改变了它我的意思是:string typeName = $"{yourNameSpace}.CertificatesMonitor";
  • 循环在 RoutineCheck() 方法内部,在 Main() 方法的计时器中(它是控制台应用程序),但它仍然是相同的命名空间;)但是是的,它在不同的类中,然后“监控”方法...
【解决方案2】:

thisType.GetMethod("{monitorName}.SingleCheck") 无法工作,原因有二。 1)您忘记了字符串插值 $-sign,因此正在搜索一个名为“{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>());
}

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

已编辑:根据朱梦的评论更改了类型发现GetType(monitorName)确实需要全名。

【讨论】:

  • 循环在定时器中的 RoutineCheck() 内部,但它仍然是同一个命名空间;)
  • @MongZhu 你说得对。我更改了类型发现部分。
猜你喜欢
  • 2011-11-05
  • 1970-01-01
  • 2011-08-26
  • 1970-01-01
  • 1970-01-01
  • 2013-09-18
  • 2015-09-05
  • 2017-03-30
  • 2014-09-09
相关资源
最近更新 更多