2010-07-08 127 views
4

我在C#初學者和有困難的時候認識的C#活動..這本書我讀(圖解C#2008)給出了一個例子吧,有我需要問一些事情關於,所以我會在這裏通過代碼,並指出我不明白的東西。需要幫助瞭解事件在C#

public class MyTimerClass 
{ 
    public event EventHandler Elapsed; 
    private void OnOneSecond(object source, EventArgs args) 
    { 
    if (Elapsed != null)     
    Elapsed(source, args); 
    } 
} 

class ClassA 
{ 
    public void TimerHandlerA(object obj, EventArgs e) // Event handler 
    { 
     Console.WriteLine("Class A handler called"); 
    } 
} 

class ClassB 
{ 
    public static void TimerHandlerB(object obj, EventArgs e) // Static 
    { 
     Console.WriteLine("Class B handler called"); 
    } 
} 

class Program 
{ 
    static void Main() 
    { 
     ClassA ca = new ClassA(); // Create the class object. 
     MyTimerClass mc = new MyTimerClass(); // Create the timer object. 
     mc.Elapsed += ca.TimerHandlerA; // Add handler A -- instance. 
     mc.Elapsed += ClassB.TimerHandlerB; // Add handler B -- static. 
     Thread.Sleep(2250); 
    } 
} 

好了,現在這裏public event EventHandler Elapsed; 這是private void OnOneSecond(object source, EventArgs args)我知道,二本上線後是檢查事件包含方法或沒有,但什麼是OnOneSecound申請宣告該事件發生後的線路?或何時被調用?或它的名字是什麼..這不是事件處理程序,我猜對了嗎? ElapsedOnOneSecond之間有什麼關係?

遺憾的新手問題..並提前:)

回答

7

的OnOneSecond方法將在內部被MyTimerClass時,它需要調用事件被調用。

這是由最控件,包括微軟的人使用的公共模式。

基本上你不需要檢查事件是否設置在多個地方,你只需要在這一個方法中進行調用,然後在內部調用此方法來引發事件。

我傾向於不事件參數傳遞給該方法OnXXX雖然,例如。

public event EventHandler<EventArgs> SomeEvent; 
protected virtual void OnSomeEvent() 
{ 
    if (this.SomeEvent !=null) 
    { 
     this.SomeEvent.Invoke(this,EventArgs.Empty); 
    } 
} 

然後提高它

this.OnSomeEvent(); 
+0

那麼,什麼你說的是OnOneSecond方法在功能上只是一個「額外」在這個例子嗎? – StingyJack 2010-07-08 12:15:57

+0

由於MyTimerClass什麼都不做,它只是沒有使用。 – sunside 2010-07-08 12:24:54

0

這可讓您手動火從登該類事件的感謝。

這是提高內部事件,這就是爲什麼它是私有的標準模式。

0

OnOneSecond僅僅是定義引發事件的輔助方法。您可以使用事件,而這樣的方法,它僅僅是一個既定的模式來包裝用與在開頭的名稱的方法的if (Elapsed != null)檢查...

從技術上講,你可以只使用Elapsed(source, args)代替OnOneSecond(source, args),但這將引發NullReferenceException如果沒有註冊聽衆。

2

這是方法,你叫安全引發事件。

的問題是,你基本上可以稱之爲

Elapsed(source, args) 

,但如果有連接的情況下沒有人,這將引發一個參考空例外。因爲事件是空的,當沒有人聽到它。

更好的解決方案是,您直接添加訂閱者到事件。那麼你可以直接調用它。因爲總會有訂戶。

public event Action<EventArgs> Elapsed = val => { }; 

(注意與它=直接分配。val => { }是Lambda表達式,限定了空的訂戶。)

另外,如果你想做很多事件的東西,這是正確的解決方案,看看Reactive Framework for .net

0

事件是一種機制,讓我們知道發生了一些有趣的事情。

事件使用代表來維護訂戶列表。委託持有訂閱事件處理方法的引用,但不知道已定義事件處理方法的類。這意味着引發事件的班級與訂閱該事件的班級沒有直接聯繫。

因此,使用事件會使應用程序中的類鬆散地相互耦合。這是在應用程序設計中使用事件和委託的優勢。

欲瞭解更多信息,請參閱Events in C# explained in detail