1

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::Do 中知道它是从 Foo1 调用的?

4

4 回答 4

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);
   }
}
于 2013-01-02T13:02:29.740 回答
1

执行此操作的“正确”方法是更改​​ Do 的签名:

void Do(object sender)

然后当调用时:

m_inner.Do(this);

否则,您将使用调用堆栈和一些反射。

于 2013-01-02T13:02:41.370 回答
1

有三种方法可以处理这个问题。第一个是传递给方法的发送者对象,就像 .Net 事件中包含的那样。这以一种非常明显的方式将发送者暴露给调用者,并允许该方法回调发送者。但是,如果代码是安全敏感的(例如,确保仅从库 X 调用此方法),则不适合。

第二种方法是System.Diagnostics.StackTrace类。请参阅如何获取当前行号?举个例子。您可以从元数据中检查调用类型和程序集。

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

于 2013-01-02T13:09:38.527 回答
0

为了完整起见,我添加了这个,但请注意,它在构造函数的情况下没有多大帮助,因为调用者的方法名总是.ctor; 但:

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

现在,像这样的调用:

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

"SomeMethod"作为caller. 正如我所提到的,它对构造函数效果不佳,这为您提供了两种选择:

  • 明确地传递名称;someObj.Do("SyntheticNameHere");
  • 添加一个命名适当的本地方法来调用Do(似乎有点过分)
于 2013-01-02T13:12:06.500 回答