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调用它?
答案 0 :(得分:1)
您有什么理由不能使用发件人对象,与事件类似?
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);
}
}
答案 1 :(得分:1)
执行此操作的“正确”方法是更改Do:
的签名void Do(object sender)
然后被叫:
m_inner.Do(this);
否则你将使用调用堆栈和一些反射。
答案 2 :(得分:1)
有三种方法可以解决这个问题。第一个是传递给方法的发送方对象,就像.Net事件中包含的那样。这会以非常明显的方式将发件人暴露给调用者,并允许该方法回调给发件人。但是,如果代码对安全性敏感(例如,确保仅从库X调用此方法),则不适合。
第二种方式是System.Diagnostics.StackTrace类。有关其用法的示例,请参见How do I get the current line number?。您可以从元数据中检查调用类型和程序集。
第三,如果您不介意向方法添加可选参数,则使用CallerMemberName和CallerFilePath属性。但是,这可能不是你想要的。但是,与StackTrace方法不同,这可以通过混淆来实现。
答案 3 :(得分:0)
我是为了完整性而添加它,但请注意,对于构造函数,不有很多帮助,因为调用者的方法名将始终为.ctor
;但是:
public void Do([CallerMemberName] string caller = null)
{
Console.WriteLine(caller);
}
现在,像是这样的电话:
void SomeMethod() {
someObj.Do();
}
将"SomeMethod"
作为caller
传递。正如我所提到的,它对构造函数也不起作用,它为您提供了两个选项:
someObj.Do("SyntheticNameHere");
Do
(似乎有点过分)