检测c#中哪个对象调用了该方法
本文关键字:调用 方法 对象 检测 | 更新日期: 2023-09-27 17:50:29
在c#中是否有一种方法来检测哪个对象调用了一个方法?
例如:
class Foo1
{
Foo2 m_inner = null
Foo1()
{
m_inner = new Foo2();
m_inner.Do();
}
}
class Foo2
{
Foo2()
{
}
void Do()
{
//Here I want to know that Foo1 called it.
}
}
是否有可能知道在Foo2::做,它是从Foo1调用?
正确的方法是修改do的签名:
void Do(object sender)
调用时:
m_inner.Do(this);
否则你将使用调用堆栈和一些反射
你为什么不能像使用事件一样使用发送者对象呢?
class Foo2
{
Foo2() {}
void Do(object sender)
{
if(sender is Foo1)
Console.Writeline("Sent from Foo1");
}
}
使用class Foo1
{
Foo2 m_inner = null
Foo1()
{
m_inner = new Foo2();
m_inner.Do(this);
}
}
有三种处理方法。第一个是传递给方法的发送方对象,就像. net事件中包含的那样。这以一种非常明显的方式将发送方暴露给调用方,并允许该方法回调发送方。但是,如果代码对安全性敏感(例如,确保该方法只能从库X调用),则不适合这样做。
第二种方法是System.Diagnostics.StackTrace类。看我如何得到当前的行号?举个例子。您可以从元数据中检查调用类型和程序集。如果您不介意为方法添加可选参数,第三种方法是使用CallerMemberName和CallerFilePath属性。然而,这可能不是您想要的。然而,与StackTrace方法不同,这是通过混淆实现的。
我添加这一点是为了完整性,但请注意,它在构造函数的情况下没有有多大帮助,因为调用者的方法名称将始终是.ctor
;但是:
public void Do([CallerMemberName] string caller = null)
{
Console.WriteLine(caller);
}
现在,像这样的调用:
void SomeMethod() {
someObj.Do();
}
将"SomeMethod"
作为caller
传入。正如我提到的,它不能很好地用于构造函数,构造函数提供了两个选项:
- 显式传递名称;
someObj.Do("SyntheticNameHere");
- 添加一个恰当命名的本地方法,调用
Do
(似乎有点夸张)