开发者

C# like events in D programming language

I recently finished a 6-month internship at a company that uses C# for the most part of their programming. During this time I first used and got accustomed to the C# way of doing events. Like shown below:

acc.AccountBalanceLow += new AccountBalanceDelegate(atm.AccountToLow);
acc.AccountBalanceLow +=new Account开发者_开发技巧BalanceDelegate(atm.AccountToLowAgain);

Does D support such constructs? I'd imagine one could be created by the user by using operator overloading, but I'm not entirely sure. If it's not possible what would then be a common excepted way of doing it then?


The equivalent construct in D is to use Signals and Slots. This is a different means of implementing the Observer Pattern, which is effectively what a C# event does.


D (and C++) use an analogous pattern called signals and slots.


If you're feeling the need to use the C# style-events instead of signals and slots, they're extremely simple to implement:

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;
    }
}


Here is an example of c# style events using signals, slots, and a templates:

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);
    }
}

declaration:

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

instantiation:

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

fire event:

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

observer registration:

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

    void handleEventOfInt(int g)
    { /*do something */ }
    void handleEventOfStringAndInt(string str, int g)
    { /*do something */ }


Check out DFL's event system. It works EXACTLY the same way as C# .NET.

DFL Event Example

Download DFL, grab the events module and use it the way you like. I modified it to use variadic template arguments. This gives maximum flexibility.

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜