2011-01-26 87 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 */ }