2011-01-26 91 views
10

我最近在一家使用C#的公司中完成了爲期6個月的實習工作,而這些公司大部分的編程工作都是在這個公司完成的。在此期間,我首先習慣了C#做事件的方式。如下圖所示:D編程語言中的C#事件

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

D是否支持這樣的構造?我想可以通過使用操作符重載來創建,但我不完全確定。如果這是不可能的,那麼這將是一種常見的例外方式呢?

回答

1

如果你覺得需要使用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; 
    } 
} 
1

下面是使用的信號,槽,和一個模板的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 */ }