如何获取在C#(DotNet)中使用反射从方法调用的方法的列表,或者如何检查是否使用反射从Method2调用方法1?
正如其他人指出的那样,使用反射基本上是不可能做到的。您必须自己解析方法的IL字节码才能找到调用。幸运的是,有一个名为Mono Cecil的美丽项目(也可以在nuget上找到),它为您完成了所有艰苦的工作。这是一个最小的示例,说明如何使用Mono Cecil解决您的问题:
static class MethodDefinitionExtensions
{
public static bool CallsMethod(this MethodDefinition caller,
MethodDefinition callee)
{
return caller.Body.Instructions.Any(x =>
x.OpCode == OpCodes.Call && x.Operand == callee);
}
}
class Program
{
private static AssemblyDefinition _assembly = AssemblyDefinition.ReadAssembly(
System.Reflection.Assembly.GetExecutingAssembly().Location);
private static void Method1()
{
Method2();
}
private static void Method2()
{
Method1();
Method3();
}
private static void Method3()
{
Method1();
}
private static IEnumerable<MethodDefinition> GetMethodsCalled(
MethodDefinition caller)
{
return caller.Body.Instructions
.Where(x => x.OpCode == OpCodes.Call)
.Select(x => (MethodDefinition)x.Operand);
}
private static MethodDefinition GetMethod(string name)
{
TypeDefinition programType = _assembly.MainModule.Types
.FirstOrDefault(x => x.Name == "Program");
return programType.Methods.First(x => x.Name == name);
}
public static void Main(string[] args)
{
MethodDefinition method1 = GetMethod("Method1");
MethodDefinition method2 = GetMethod("Method2");
MethodDefinition method3 = GetMethod("Method3");
Debug.Assert(method1.CallsMethod(method3) == false);
Debug.Assert(method1.CallsMethod(method2) == true);
Debug.Assert(method3.CallsMethod(method1) == true);
Debug.Assert(GetMethodsCalled(method2).SequenceEqual(
new List<MethodDefinition> { method1, method3 }));
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句