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

有没有办法在c#中获取对调用对象的引用?,c#,reflection,C#,Reflection,我想知道的是,是否有可能(例如)遍历堆栈帧,检查每个调用对象以查看是否与接口匹配,如果匹配,则从中提取一些数据 是的,我知道这是不好的做法,我想知道这是否可能。请看这个问题: 它不是重复的,但是这个问题的答案也会回答你的问题。不,没有-至少在不使用某种描述的分析/调试API的情况下没有。您可以遍历堆栈以找到调用方法,但需要注意的是,由于JIT优化,调用方法非常慢,并且可能不准确。这不会告诉您调用对象是什么(如果确实有一个对象)。如果要获取类型,可以尝试以下方法: new StackFrame(

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

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

请看这个问题:


它不是重复的,但是这个问题的答案也会回答你的问题。

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

如果要获取类型,可以尝试以下方法:

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();

    }
}
我们应该让程序进入控制台两次,当您在调试器中运行时,您就会这样做。当您在释放模式下不使用调试器运行时,您将从第一个测试函数获得输出。这可能是因为内联非常复杂,但是,第二个方法会导致空引用异常


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

不太可能——因为虽然获取调用方法是可行的,但这并不能告诉您进行调用的对象的实际类型。例如,它可能位于BaseClass.Foo()中,但来自DerivedClass的实例,该实例实现了Andrew正在寻找的接口。它确实提供了堆栈跟踪,尽管如此。Aaaah-那么VS大概是以某种复杂的方式通过插入代码来实现的?嗯,不是通过检测代码,而是通过运行调试器API,调试器API提供各种信息——当然是有代价的。哦,我在哪里可以找到这些调试器API的更多信息?安德鲁杜克:老实说,我只是在谷歌搜索中找到,所以我让你来做这些:)我从来没有使用过调试器/探查器API-考虑到它们的低级功能,我想它们可能会很难使用。因此,这让我觉得一些日志代码太聪明了,检查StackTrace并向上帧以获得调用方法的名称。您可以在调试模式下通过简单的计数来实现这一点,但在发布模式下,有些方法会得到优化。一个很棒的提示!