C # как события в языке программирования D - PullRequest
10 голосов
/ 27 января 2011

Я недавно закончил 6-месячную стажировку в компании, которая использует C # для большей части своего программирования. За это время я впервые использовал привычный для C # способ организации событий. Как показано ниже:

acc.AccountBalanceLow += new AccountBalanceDelegate(atm.AccountToLow);
acc.AccountBalanceLow +=new AccountBalanceDelegate(atm.AccountToLowAgain);

Поддерживает ли D такие конструкции? Я мог бы предположить, что он может быть создан пользователем с использованием перегрузки операторов, но я не совсем уверен. Если это невозможно, то каков тогда будет распространенный исключительный способ сделать это?

Ответы [ 5 ]

11 голосов
/ 27 января 2011

Эквивалентная конструкция в D должна использовать Сигналы и слоты .Это другой способ реализации шаблона наблюдателя , который фактически является тем, что делает событие C #.

4 голосов
/ 27 января 2011

D (и C ++) используют аналогичный шаблон, называемый сигналы и слоты .

1 голос
/ 12 февраля 2012

Вот пример событий в стиле c # с использованием сигналов, слотов и шаблонов:

events.d:

import std.signals;

class Event(T...){
    mixin Signal!(T);       

    void broadcast(T args){ 
        emit(args);
    }       
    void opAddAssign(slot_t slot){
        connect(slot);
    }
    void opSubAssign(slot_t slot) {
        disconnect(slot);
    }
}

объявление:

    public Event!(int) onSomeEventOfInt;
    public Event!(string, int) onSomeEventOfStringAndInt;

экземпляр:

    this.onSomeEventOfInt = new Event!(int)();
    this.onSomeEventOfStringAndInt = new Event!(string, int)();

событие пожара:

    int i = 4;
    string str = "hello";
    this.onSomeEventOfInt.broadcast(i);
    this.onSomeEventOfStringAndInt.broadcast(str, 4);

регистрация наблюдателя:

    obj1.onSomeEventOfInt += &handleEventOfInt
    obj1.onSomeEventOfStringAndInt += &handleEventOfStringAndInt

    void handleEventOfInt(int g)
    { /*do something */ }
    void handleEventOfStringAndInt(string str, int g)
    { /*do something */ }
1 голос
/ 28 января 2011

Если вы чувствуете необходимость использовать события стиля C # вместо сигналов и слотов, их чрезвычайно просто реализовать:

module fluidity.core.event;

class Event {
    alias void delegate(EventArgs) handler_t;

    handler_t[] handlers;
    Object owner;

    this() {}
    this(Object o) { owner = o; }

    void attach(handler_t handler) {
        if (handler)
            handlers ~= handler;
    }

    void detach(handler_t handler) {
        int i = -1;
        foreach (j, h; handlers)
        {
            if (h is handler)
            {
                i = j;
                break;
            }
        }

        if (i > -1)
            handlers = handlers[0..i] ~ handlers[i+1..$];
    }

    void raise() { raise(new EventArgs(owner)); }
    void raise(EventArgs e) {
        // call all handlers
        foreach (handler; handlers)
        {
            if (handler)
                handler(e);
        }
    }

    void opAddAssign(handler_t handler) {
        attach(handler);
    }

    void opSubAssign(handler_t handler) {
        detach(handler);
    }

}

class EventArgs {
    Object source;
    bool handled;

    void handle() { handled = true; }

    this() {}
    this(Object s) {
        source = s;
    }
}
0 голосов
/ 05 февраля 2011

Проверьте систему событий DFL.Он работает точно так же, как C # .NET.

Пример события DFL

Загрузите DFL, возьмите модуль событий и используйте его так, как вам нравится.Я изменил его, чтобы использовать переменные аргументы шаблона.Это дает максимальную гибкость.

http://www.dprogramming.com/dfl098.zip

...