检查是否在实例方法中访问了该指针

本文关键字:指针 访问 是否 实例方法 检查 | 更新日期: 2023-09-27 17:50:16

我试图检测this指针是否在dot net实例方法中被访问。可以是对实例方法的调用,对成员变量的访问等等。

如果我能从IL中找出答案,目前正在研究Reflection: MethodBase.GetMethodBody

检查是否在实例方法中访问了该指针

使用单声道。反射:

// using Mono.Reflection;
public static bool ContainsThis(MethodBase method)
{
    if (method.IsStatic)
    {
        return false;
    }
    IList<Instruction> instructions = method.GetInstructions();
    return instructions.Any(x => x.OpCode == OpCodes.Ldarg_0);
}

使用示例:

public class Foo
{
    private int bar;
    public int Bar
    {
        get { return bar; }
        set { }
    }
    public void CouldBeStatic()
    {
        Console.WriteLine("Hello world");
    }
    public void UsesThis(int p1, int p2, int p3, int p4, int p5)
    {
        Console.WriteLine(Bar);
        Console.WriteLine(p5);
    }
}
MethodBase m1 = typeof(Foo).GetMethod("CouldBeStatic");
MethodBase m2 = typeof(Foo).GetMethod("UsesThis");
MethodBase p1 = typeof(Foo).GetProperty("Bar").GetGetMethod();
MethodBase p2 = typeof(Foo).GetProperty("Bar").GetSetMethod();
bool r1 = ContainsThis(m1); // false
bool r2 = ContainsThis(m2); // true
bool r3 = ContainsThis(p1); // true
bool r4 = ContainsThis(p2); // false

记住using Mono.Reflection

啊……它是如何工作的……this是一个"隐藏"参数,是第一个。要将IL代码中的参数加载到堆栈中,可以使用ldarg_#,其中#是参数编号。因此,在实例方法中,ldarg_0this加载到堆栈中。