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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/420541/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 02:43:34  来源:igfitidea点击:

Is there any way to get a reference to the calling object in c#?

c#reflection

提问by Andrew Ducker

What I'm wondering is if it's possible to (for instance) to walk up the stack frames, checking each calling object to see if matches an interface, and if so extract some data from it.

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

Yes, I know it's bad practice, I'm wondering if it's possible.

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

回答by Joel Coehoorn

See this question:
Can you use reflection to find the name of the currently executing method?

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

It's not a duplicate, but the answer to that question will answer yours as well.

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

回答by Jon Skeet

No, there isn't - at least not without using a profiling/debugging API of some description. You can walk the stack to find the calling method, with the caveat that it's really slow and may be inaccurate due to JIT optimisations. That won't tell you what the calling objectis though (if indeed there is one).

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

回答by JoshBerke

If you want to get the type you can try this:

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

new StackFrame(1).GetMethod().DeclaringType

new StackFrame(1).GetMethod().DeclaringType

As Jon pointed out there might be issues if you run into JIT optimizations.

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

As for getting data from the object, I don't think it's possible.

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

Edit

编辑

Just to elaborate on the optimization issue, take the following code:

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

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

    }
}

We should get Program to the console twice, and when you run within the debugger you do. When you run without the debugger in release mode, you get the output from the first Test function. Which is probably because it is to complex to be inlined, however, the second method causes a null reference exception.

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

Another danger with this code is that at MS improves the JIT compiler what might have worked in 2.0 could crash and burn in future versions.

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