有没有办法在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并向上帧以获得调用方法的名称。您可以在调试模式下通过简单的计数来实现这一点,但在发布模式下,有些方法会得到优化。一个很棒的提示!