ResolveMethod()返回完全不同的方法

时间:2018-03-11 19:15:05

标签: c# .net reflection

我正在解析.NET DLL中的方法,并注意到Module.ResolveMethod()返回的方法与原始方法完全不同。我正在指定方法的确切MetadataToken,所以对我来说完全没有意义,为什么我最终会得到除原始方法之外的任何其他内容。

在下面的例子中,我有' Dispose()'方法。我抓住它的元数据令牌并解决它,却发现我现在有了#BackBoChanged(System.EventArgs)'方法

static void Main(string[] args)
    {
        Assembly assembly = Assembly.LoadFrom(@"C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Windows.Forms.dll");
        MethodInfo method = assembly.GetModules()[0].GetTypes()[300].GetMethods()[362];
        Console.WriteLine(method); //Returns 'Void Dispose()'

        MethodInfo method2 = (MethodInfo)assembly.GetModules()[0].ResolveMethod(method.MetadataToken);
        Console.WriteLine(method2); //Returns 'Void OnBackColorChanged(System.EventArgs)' ...why?
    }

1 个答案:

答案 0 :(得分:3)

Button,通过长继承链,继承自Component类,它实现IDisposable并具有void Dispose()方法。这是您通过

获得的方法
assembly.GetModules()[0].GetTypes()[300].GetMethods()[362];

由于此方法是在Component类型System上声明的,因此使用其元数据句柄从完全不同的模块(System.Windows.Forms)解析方法会导致随机结果。

如果您只想获得在此具体类型上声明的方法 - 请使用BindingFlags.DeclaredOnly

var allMethods = type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);

但请注意,这将仅返回Button上声明的方法,而不返回任何父类型,即使该父类型属于同一模块。

或者 - 按模块过滤:

Assembly assembly = Assembly.LoadFrom(@"C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Windows.Forms.dll");
var module = assembly.GetModules()[0];
var type = module.GetTypes()[300];
var allMethods = type.GetMethods().Where(c => c.Module == module).ToArray();