C# 如何在C中使用反射获取从方法调用的方法列表#
如何获取在C#(DotNet)中使用反射的方法调用的方法列表,或者如何检查是否使用反射从方法2调用了方法1?正如其他人所指出的,使用反射基本上不可能做到这一点。为了找到调用,您必须自己解析方法的IL字节码。幸运的是,有一个名为(也可从上获得)的漂亮项目,它为您完成了所有的艰苦工作。这里有一个简单的例子来说明如何使用Mono Cecil解决您的问题:C# 如何在C中使用反射获取从方法调用的方法列表#,c#,reflection,system.reflection,C#,Reflection,System.reflection,如何获取在C#(DotNet)中使用反射的方法调用的方法列表,或者如何检查是否使用反射从方法2调用了方法1?正如其他人所指出的,使用反射基本上不可能做到这一点。为了找到调用,您必须自己解析方法的IL字节码。幸运的是,有一个名为(也可从上获得)的漂亮项目,它为您完成了所有的艰苦工作。这里有一个简单的例子来说明如何使用Mono Cecil解决您的问题: static class MethodDefinitionExtensions { public static bool CallsMeth
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 }));
}
}
静态类方法定义扩展
{
公共静态bool调用方法(此方法定义调用方,
方法定义(被调用方)
{
返回caller.Body.Instructions.Any(x=>
x、 操作码==操作码.Call&&x.操作数==被调用方);
}
}
班级计划
{
私有静态AssemblyDefinition\u assembly=AssemblyDefinition.ReadAssembly(
System.Reflection.Assembly.GetExecutionGassembly().Location);
私有静态void方法1()
{
方法2();
}
私有静态void方法2()
{
方法1();
方法3();
}
私有静态void方法3()
{
方法1();
}
私有静态IEnumerable GetMethodScaled(
方法定义(调用方)
{
返回caller.Body.Instructions
.Where(x=>x.OpCode==OpCode.Call)
.Select(x=>(MethodDefinition)x.Operand);
}
私有静态方法定义GetMethod(字符串名称)
{
TypeDefinition programType=\u assembly.MainModule.Types
.FirstOrDefault(x=>x.Name==“程序”);
首先返回programType.Methods(x=>x.Name==Name);
}
公共静态void Main(字符串[]args)
{
MethodDefinition method1=GetMethod(“method1”);
MethodDefinition method2=GetMethod(“method2”);
MethodDefinition method3=GetMethod(“method3”);
Debug.Assert(method1.CallsMethod(method3)=false);
Assert(method1.CallsMethod(method2)==true);
Assert(method3.CallsMethod(method1)==true);
Assert(getMethodScaled(method2).SequenceEqual(
新列表{method1,method3});
}
}
使用反射无法实现这一点。反射是为了提供元数据——您需要一个反编译器和/或代码分析来挖掘源代码。它可以告诉你房子的颜色、大小和地址,但不能告诉你里面有什么家具。你想达到什么目的?这有帮助吗GetMethodScaled
应转换为MethodReference
而不是MethodDefinition