C# 通过反射找到特定的方法

C# 通过反射找到特定的方法,c#,reflection,C#,Reflection,假设一个类中有两个公共方法: public class SomeClass { public bool DoSomething(int param1) { return param1 == 30; } public bool DoSomethingElse(int param1) { param1 *= 2; return param1 == 30; } } 我可以编写以下代码来使用反射获取这两种

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

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
,我可以使用
方法[1]

但是,假设下次编译此类时它们交换了位置。我会以
DoSomething
而告终

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

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


注意:我正在寻找的方法在每次编译时可能会更改名称,因此简单地搜索它们的名称也不会起作用。从技术上讲,您可以分析方法'IL代码;让我们检查第一批
10
IL代码中是否有
*2

代码:

  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();
  DoSomethingElse
我们来看看,

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

  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();
  DoSomethingElse

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

从技术上讲,您可以分析方法'IL代码;让我们检查第一批
10
IL代码中是否有
*2

代码:

  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();
  DoSomethingElse
我们来看看,

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

  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();
  DoSomethingElse

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

您可以使用自定义的
属性
来装饰该方法,然后使用LINQ检查该属性的方法。@AlphaDelta我不是编写源代码的人。我无法控制这一点。我看不出用简单的C#反射来实现这一点。也许是一个有用的例子。一个适合您使用的简单示例:您可以检查许多内容,例如方法签名(参数)、返回类型,甚至对方法本身的IL代码进行分析。但我不确定你问的是可能的,因为你无法控制源头;所有潜在的元数据都是可变的。这里的实际问题是什么元数据保持不变。如果你能问清楚,你可以回答你的问题。我们不能。你可以用一个自定义的
属性来修饰这个方法,然后用LINQ检查该属性的方法。@AlphaDelta我不是编写源代码的人。我无法控制这一点。我看不出用简单的C#反射来实现这一点。也许是一个有用的例子。一个适合您使用的简单示例:您可以检查许多内容,例如方法签名(参数)、返回类型,甚至对方法本身的IL代码进行分析。但我不确定你问的是可能的,因为你无法控制源头;所有潜在的元数据都是可变的。这里的实际问题是什么元数据保持不变。如果你能问清楚,你可以回答你的问题。我们不能。