有没有办法在c#中获取对调用对象的引用?

And*_*ker 22 c# reflection

我想知道的是,是否可以(例如)走向堆栈帧,检查每个调用对象以查看是否匹配接口,如果是,则从中提取一些数据.

是的,我知道这是不好的做法,我想知道是否有可能.

Jon*_*eet 20

不,没有 - 至少没有使用某些描述的分析/调试API.您可以遍历堆栈以查找调用方法,但需要注意的是,由于JIT优化,它非常慢并且可能不准确.这不会告诉你调用对象是什么(如果确实有一个).

  • 哦 - 我在哪里可以找到这些调试器API的moer信息? (2认同)
  • 因此,这让我发现了一些日志代码,这些代码试图变得太聪明,检查 StackTrace 并向上帧获取调用方法的名称。您可以通过在调试模式下进行简单的计数来做到这一点,但在发布模式下,一些方法会被优化掉。一个很棒的提示! (2认同)

Jos*_*rke 5

如果你想获得类型,你可以试试这个:

new StackFrame(1).GetMethod().DeclaringType

正如 Jon 指出的那样,如果您遇到 JIT 优化,可能会出现问题。

至于从对象中获取数据,我认为这是不可能的。

编辑

只是为了详细说明优化问题,取以下代码:

class stackTest
{
    public void Test()
    {
        StackFrame sFrame = new StackFrame(1);
        if (sFrame == null)
        {
            Console.WriteLine("sFrame is null");
            return;
        }

        var method = sFrame.GetMethod();

        if (method == null)
        {
            Console.WriteLine("method is null");
            return;
        }
        Type declaringType = method.DeclaringType;
        Console.WriteLine(declaringType.Name);
    }

    public void Test2()
    {
        Console.WriteLine(new StackFrame(1).GetMethod().DeclaringType.Name);
    }
}

class Program
{
    static void Main(string[] args)
    {

        stackTest s = new stackTest();
        s.Test();
        Console.WriteLine("Doing Test2");
        s.Test2();
        Console.ReadLine();

    }
}
Run Code Online (Sandbox Code Playgroud)

我们应该两次将程序带到控制台,当您在调试器中运行时,您会这样做。当您在发布模式下不使用调试器运行时,您将获得第一个 Test 函数的输出。这可能是因为内联很复杂,但是,第二种方法会导致空引用异常。

这段代码的另一个危险是,在 MS 改进了 JIT 编译器,在 2.0 中可能工作的内容可能会在未来版本中崩溃和烧毁。


Joe*_*orn 0

看到这个问题:
你能使用反射来查找当前正在执行的方法的名称吗?

它不是重复的,但该问题的答案也将回答您的问题。