Как реализовать концепцию Signals (из Django) в C # - PullRequest
1 голос
/ 17 января 2010

Я пытаюсь реализовать сигналы от Django (http://docs.djangoproject.com/en/dev/topics/signals/), или его концепции в C #, чтобы уменьшить / устранить зависимости соединения / метода.

Пока что я хорошо копирую код, вплоть до того момента, когда я понял, что методы не являются объектами в C #, как в Python. Потом я подумал об указателях и понял, что у меня не может быть указателей на методы. Его версия на C # - это делегаты.

Тогда я понял, что у делегатов есть уникальная подпись, поэтому я не могу смешивать делегированные методы (с подписями diff) в List, или я могу?

Я немного погуглил и нашел Reactive LINQ, пока что linq выглядит потрясающе, но я до сих пор не понимаю, когда их использовать.

Итак, мой вопрос: как бы вы реализовали концепцию Signals в C #? Спасибо!

О, я упоминал, что я новичок (1 день) в C #? У меня есть опыт работы с другими языками, включая Java / C / Python.

Приветствия:)

1 Ответ

2 голосов
/ 17 января 2010

То, о чем вы здесь говорите, обычно обрабатывается как события в C #, например;

public class SomeType {
    public event EventHandler SomeEvent;
    protected virtual void OnSomeEvent() {
        EventHandler handler = SomeEvent;
        if(handler!=null) handler(this,EventArgs.Empty);
    }
    public void SomethingInteresting() {
        // blah
        OnSomeEvent(); // notify subscribers
        // blap
    }
    // ...
}

С подписчиками ...

SomeType obj = new SomeType();
//...
obj.SomeEvent += /* some handler */
//...

обработчик может быть методом, но при обсуждении сигнатур и т. Д. Наиболее распространенным способом повторного использования существующих методов с несоответствующими сигнатурами являются анонимные методы:

obj.SomeEvent += delegate { this.Text = "Done!"; };

Вы можете иметь список делегатов:

List<SomeDelegateType> list = new List<SomeDelegateType>();
list.Add(...);

но это может быть избыточно, потому что экземпляры делегатов multicast - так что вы можете сделать это более напрямую:

Action action = null;
action += delegate { Console.WriteLine("Did A");};
action += delegate { Console.WriteLine("Did B");};
action(); // does both A & B

Обратите внимание, что более сложное использование делегата может включать входящие значения аргументов - например:

int i = 24;
Func<int,int,int> func = (x,y) => (x * i) + y;
int result = func(2, 3); // 51

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

Обратите внимание, что при событиях (в частности) общим подходом является сохранение подписи:

void SomeDelegateType(object sender, SomeArgsType args);

где SomeArgsType : EventArgs - или используйте EventHandler<T>, который сделает это за вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...