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

イベントと同様に、sender オブジェクトを使用できない理由はありますか?

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

これを処理するには 3 つの方法があります。1 つ目は、.Net イベントに含まれているような、メソッドに渡される送信者オブジェクトです。これにより、非常に明白な方法で送信者が呼び出し元に公開され、メソッドが送信者にコールバックできるようになります。ただし、コードがセキュリティ上重要な場合 (たとえば、このメソッドがライブラリ X からのみ呼び出されるようにするなど)、これは適切ではありません。

2 つ目の方法は、System.Diagnostics.StackTraceクラスです。現在の行番号を取得する方法を参照してください。その使用例について。呼び出し元の型とアセンブリをメタデータから調べることができます。

3 つ目は、オプションの引数をメソッドに追加してもかまわない場合は、CallerMemberNameおよびCallerFilePath属性を使用することです。ただし、これはおそらくここで必要なものではありません。ただし、これは 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ます。私が言及したように、それはコンストラクターにはうまく機能しません。これには 2 つのオプションがあります。

  • 名前を明示的に渡します。someObj.Do("SyntheticNameHere");
  • 呼び出す適切な名前のローカルメソッドを追加しますDo(やり過ぎのようです)
于 2013-01-02T13:12:06.500 に答える