Вложенный статический класс C # - PullRequest
0 голосов
/ 09 июня 2011

Мне интересно, могу ли я получить объект, который вызвал статический метод статического класса, например:

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 (это, comunicateWith, MSG)?

Ответы [ 4 ]

2 голосов
/ 09 июня 2011

Это возможно при использовании обхода стека (при условии, что вы предотвращаете встроенный статический метод), но обычно это плохая идея.

Получение имени вызывающего метода из метода

Делать это в целях отладки, если нормально. Делать это из-за того, что вам лень явно вписывать это в обычный поток программ, - очень плохой дизайн. Поэтому в вашем случае я настоятельно рекомендую передать его вручную.


Немного не по теме, но я уверен, что ваши занятия не должны быть статичными. Статические методы хороши для простых функций без побочных эффектов (хорошие примеры см. Math или Enumerable). Ваш TelephoneLine должен быть как минимум синглтоном, но, IMO, вы должны просто использовать внедрение зависимостей и внедрить один его экземпляр.

0 голосов
/ 09 июня 2011

Класс TelephoneLine на самом деле не должен принадлежать человеку (они принадлежат телефонным компаниям!), И они не должны быть статичными (статический == запах кода).

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!
  }
}
0 голосов
/ 09 июня 2011

Одним из способов будет определение общего интерфейса между лицом и службой и использование его контракта для передачи данных:

Общее решение может быть избыточным для вложенного частного класса обслуживания, но вы можете захотеть расширить возможности телефонных звонков позже и реорганизовать его как общедоступные, например, автоматические вызовы службы или что-то в этом роде.

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;}
}
0 голосов
/ 09 июня 2011

Простой ответ - нет.Многие собственные события .NET (по щелчку и т. Д. В WinForms или ASP) требуют, чтобы вы передали аргумент 'sender'.

Вы можете посмотреть на стек, чтобы получить имя метода и, возможно, даже типвызывающего, но вы определенно не можете получить конкретный объект, который вызвал функцию.

...