我正在解析.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?
}
答案 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();