0

静的クラスexの静的メソッドを呼び出したオブジェクトを取得できるかどうか疑問に思っています:

public class Person
{
    private static class TelephoneLine
    {
        public static string sharedString = string.Empty;
        public static void NotifyOnCall()
        {
            //notify if someone call this person
        }
        public static void Comunicate(Person comunicateWith, string message)
        {
            sharedString = "Sender: " /* Object which called that method */ + " To: " + comunicateWith.Name +
                           " said: " + message;
        }
    }
    public Person(string name)
    {
        Name = name;
    }
    string Name;
    public void CallTo(Person person, string message)
    {
        TelephoneLine.Comunicate(person, message);
    }
    public void ShowCall()
    {
        Console.Write(TelephoneLine.sharedString);
    }
}

}

ThelephoneLine.Comunicate(this, comunicateWith, msg) のパラメーターで渡す以外に、「Sender」を取得する可能性はありますか?

4

4 に答える 4

2

スタック クロールを使用することは可能ですが (静的メソッドがインライン化されないようにする場合)、通常はお勧めできません。

メソッド内から呼び出しメソッド名を取得する

問題がなければ、デバッグ目的でこれを行います。通常のプログラムフローに明示的に書き込むのが面倒だからという理由でそれを行うのは、非常に悪い設計です。したがって、あなたの場合、手動で渡すことを強くお勧めします。


少しトピックから外れていますが、クラスを静的にするべきではないと確信しています。静的メソッドは、単純な副作用のない関数に適しています (良い例についてはMathまたはEnumerableを参照してください)。TelephoneLine少なくともシングルトンである必要がありますが、IMO は単に依存性注入を使用して、その単一のインスタンスを注入する必要があります。

于 2011-06-09T14:29:25.510 に答える
0

簡単な答えはノーです。多くの .NET 独自のイベント (WinForms または ASP での Clicked など) では、'sender' 引数を渡す必要があります。

スタックを調べて、メソッドの名前と呼び出し元の型を取得することはできますが、関数を呼び出した特定のオブジェクトを取得することはできません。

于 2011-06-09T14:31:35.277 に答える
0

TelephoneLine クラスは、実際には Person によって所有されるべきではなく (電話会社によって所有されています!)、静的であってはなりません (静的 == コードの匂い)。

class TelephoneLine
{
  public TelephoneLine (Person sender, Person receiver)
  {
    m_sender = sender;
    m_receiver = receiver;
  }

  public void Send (Person from, String message)
  {
    if (from == sender)
    {
       output "From: " + m_sender + " To: " + m_receiver + " Message: " + message;
    }
    else
    {
       output "From: " + m_receiver + " To: " + m_sender + " Message: " + message;
    }
  }

  Person m_sender, m_receiver;
};

class Person
{
  public void MakeCall (Person receiver, string message)
  {
     TelephoneLine line = new TelephoneLine (this, receiver);
     line.Send (this, message);
  }
}

実際、TelephoneLine オブジェクトは別のものによって所有されている必要があります。

class Exchange
{
  public TelephoneLine MakeCall (Person from, Person to)
  {
    // check that 'to' can receive call first!
    return new TelephoneLine (from, to);
  }
};

class Person
{
  public void MakeCall (Person receiver, string message)
  {
     TelephoneLine line = the_exchange.MakeCall (this, receiver);
     if (line != null)
     {
       line.Send (this, message);
     }
     // else, receiver not listening!
  }
}
于 2011-06-09T15:00:41.890 に答える
0

1 つの方法は、人とサービスの間に共通のインターフェイスを定義し、そのコントラクトを使用してデータを渡すことです。

一般的なソリューションは、ネストされたプライベート サービス クラスには過剰かもしれませんが、後で電話をかけることができるものを拡張し、それをパブリックにリファクタリングしたい場合があります。たとえば、自動化されたサービス コールなどです。

public interface ICallable { string CallerIdString(); }

public class Person : ICallable
{
    private static class TelephoneLine
    {
        public static string sharedString = string.Empty;
        public static void NotifyOnCall()
        {
            //notify if someone call this person
        }
        public static void Comunicate<TCaller>(TCaller Caller, Person comunicateWith, string message) where TCaller : ICallable
        {
            sharedString = "Sender: " + Caller.CallerIdString() + " To: " + comunicateWith.Name +
                           " said: " + message;
                           sharedString.Dump();
        }
    }
    public Person(string name)
    {
        Name = name;
    }
    string Name;
    public void CallTo(Person person, string message)
    {
        TelephoneLine.Comunicate<Person>(this, person, message);
    }
    public void ShowCall()
    {
        Console.Write(TelephoneLine.sharedString);
    }

    public string CallerIdString() { return this.Name;}
}
于 2011-06-09T14:34:09.250 に答える