检测哪个对象在C#中调用了该方法

时间:2013-01-02 13:00:10

标签: c#

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调用它?

4 个答案:

答案 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?。您可以从元数据中检查调用类型和程序集。

第三,如果您不介意向方法添加可选参数,则使用CallerMemberNameCallerFilePath属性。但是,这可能不是你想要的。但是,与StackTrace方法不同,这可以通过混淆来实现。

答案 3 :(得分:0)

我是为了完整性而添加它,但请注意,对于构造函数,有很多帮助,因为调用者的方法名将始终为.ctor;但是:

public void Do([CallerMemberName] string caller = null)
{
    Console.WriteLine(caller);
}

现在,像是这样的电话:

void SomeMethod() {
    someObj.Do();
}

"SomeMethod"作为caller传递。正如我所提到的,它对构造函数也不起作用,它为您提供了两个选项:

  • 明确传递名称; someObj.Do("SyntheticNameHere");
  • 添加一个名称恰当的本地方法,调用Do(似乎有点过分)