【问题标题】:Finding a specific method via reflection通过反射找到特定的方法
【发布时间】:2020-01-30 23:11:08
【问题描述】:

假设我们在一个类中有两个公共方法:

public class SomeClass
{
    public bool DoSomething(int param1)
    {
        return param1 == 30;
    }

    public bool DoSomethingElse(int param1)
    {
        param1 *= 2;
        return param1 == 30;
    }
}

我可以编写以下代码来使用反射来获取这两种方法:

MethodInfo[] methods = typeof(SomeClass).GetMethods(BindingFlags.Public | BindingFlags.Instance)
                       .Where(x => x.ReturnType == typeof(bool)
                              && x.GetParameters().Length == 1
                              && x.GetParameters()[0].ParameterType == typeof(int)).ToArray();

假设我只想要DoSomethingElse,我可以使用methods[1]

但是,假设他们在下次编译此类时交换了位置。我最终会选择DoSomething

这两种方法的唯一区别是DoSomethingElse在检查之前将参数乘以2。

我是否可以对反射进行任何其他检查以确保我始终获得DoSomethingElse

注意:我要查找的方法可能会在每次编译时更改其名称,因此仅搜索其名称也不起作用。

【问题讨论】:

  • 您可以使用自定义Attribute 装饰方法,然后使用 LINQ 检查该属性的方法。
  • @AlphaDelta 我不是编写源代码的人。我无法控制。
  • 无论如何我都看不到用简单的 C# 反射来做到这一点。可能是Cecil 的用例。一个适合您使用的简单示例:stackoverflow.com/questions/49923757/…
  • 您可以检查很多东西,例如方法签名(参数)、返回类型,甚至是对方法本身的 IL 代码的分析。但是我不确定您要问的是可能的,因为您无法控制来源;所有潜在的元数据都是可变的。
  • 这里的实际问题是什么元数据保持恒定。如果你能回答,你就可以回答你的问题。我们不能。

标签: c# reflection


【解决方案1】:

技术上,你可以分析方法的IL代码;让我们检查一下在第一个10 IL 代码中是否有* 2

https://en.wikipedia.org/wiki/List_of_CIL_instructions

代码:

  MethodInfo[] methods = GetType()
    .GetMethods(BindingFlags.Public | BindingFlags.Instance)
    .Where(x => x.ReturnType == typeof(bool)
           && x.GetParameters().Length == 1
           && x.GetParameters()[0].ParameterType == typeof(int))
    .Where(m => m
       .GetMethodBody()
       .GetILAsByteArray()
       .Take(10)                  // take first 10 IL codes
       .SkipWhile(b => b != 0x18) // ldc.i4.2 : load 2
       .Any(b => b == 0x5A))      // mul      : multiply 
    .ToArray();

让我们看看:

  Console.Write(string.Join(Environment.NewLine, methods.Select(m => m.Name)));

结果:

  DoSomethingElse

但是,我强烈建议使用特定方法 Name 或使用 属性 等标记方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-25
    • 2014-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-16
    相关资源
    最近更新 更多