2009-01-20 49 views

回答

16

C++/CLI允許您在custom event處理程序中覆蓋raise,因此您不必在引發事件時測試null或進行復制。當然,在你的自定義raise裏面,你仍然需要這樣做。

例,改編自MSDN的正確性:

public delegate void f(int); 

public ref struct E { 
    f^_E; 
public: 
    void handler(int i) { 
     System::Console::WriteLine(i); 
    } 

    E() { 
     _E = nullptr; 
    } 

    event f^ Event { 
     void add(f^d) { 
     _E += d; 
     } 
     void remove(f^d) { 
     _E -= d; 
     } 
     void raise(int i) { 
     f^ tmp = _E; 
     if (tmp) { 
      tmp->Invoke(i); 
     } 
     } 
    } 

    static void Go() { 
     E^ pE = gcnew E; 
     pE->Event += gcnew f(pE, &E::handler); 
     pE->Event(17); 
    } 
}; 

int main() { 
    E::Go(); 
} 
28

這並不是故事的全部!您通常不必擔心C++/CLI中的空事件處理程序。這些檢查的代碼是爲您生成的。考慮以下簡單的C++/CLI類。

public ref class MyClass 
{ 
public: 
    event System::EventHandler^MyEvent; 
}; 

如果你編譯這個類,並使用Reflector拆解,你會得到下面的C#代碼。

public class MyClass 
{ 
    // Fields 
    private EventHandler <backing_store>MyEvent; 

    // Events 
    public event EventHandler MyEvent 
    { 
     [MethodImpl(MethodImplOptions.Synchronized)] add 
     { 
      this.<backing_store>MyEvent = (EventHandler) Delegate.Combine(this.<backing_store>MyEvent, value); 
     } 
     [MethodImpl(MethodImplOptions.Synchronized)] remove 
     { 
      this.<backing_store>MyEvent = (EventHandler) Delegate.Remove(this.<backing_store>MyEvent, value); 
     } 
     raise 
     { 
      EventHandler <tmp> = null; 
      <tmp> = this.<backing_store>MyEvent; 
      if (<tmp> != null) 
      { 
       <tmp>(value0, value1); 
      } 
     } 
    } 
} 

通常的檢查工作正在完成。除非你真的想要自定義行爲,否則你應該感覺很自然,就像在上面的類中聲明你的事件一樣,並提升它,而不用擔心空處理器。

+0

我這個方法的問題是「raise」方法不是私有的(如在C#中)並在智能感知中顯示。 – 2010-01-08 13:34:06

7

如果你的問題是,加薪不是私人的,則明確地執行它像文檔說:

http://msdn.microsoft.com/en-us/library/5f3csfsa.aspx

總結:

如果你只是使用事件關鍵字,您創建一個「小事件」事件。編譯器生成添加/刪除/提高和委託會員爲您服務。生成的提高函數(如文檔說)檢查nullptr。瑣碎事件被記錄在這裏:

http://msdn.microsoft.com/en-us/library/4b612y2s.aspx

如果你想「更多的控制」,例如,使提高私人,那麼你必須明確地執行委員如圖所示的鏈接。您必須顯式聲明委託類型的數據成員。然後你使用事件關鍵字來聲明與事件相關的成員,如微軟例如:

// event keyword introduces the scope wherein I'm defining the required methods 
// "f" is my delegate type 
// "Event" is the unrealistic name of the event itself 
event f^ Event 
{ 
     // add is public (because the event block is public) 
     // "_E" is the private delegate data member of type "f" 
     void add(f^d) { _E += d; } 

    // making remove private 
    private: 
     void remove(f^d) { _E -= d; } 

    // making raise protected 
    protected: 
     void raise(int i) 
     { 
     // check for nullptr 
     if (_E) 
     { 
      _E->Invoke(i); 
     } 
     } 
}// end event block 

羅嗦,但它是。

-reilly。