簡體   English   中英

需要幫助了解C#中的事件

[英]Need help understanding Events in C#

我是C#的初學者,很難理解C#中的事件。我讀過的這本書(插圖C#2008)給出了一個例子,我需要問一些事情,所以我將在這里通過代碼並指出我不理解的事情。

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之間的關系是什么?

對不起新手問題..並提前感謝:)

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

這是大多數控件使用的常見模式,包括微軟控件。

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

例如,我傾向於不將事件args傳遞給OnXXX方法。

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

然后提高它

this.OnSomeEvent();

這是您調用以安全地引發事件的方法。

問題是,你基本上可以打電話

Elapsed(source, args)

但如果沒有人連接到該事件,則會引發Reference Null異常。 當事件為空時,沒有人聽到它。

更好的解決方案是,您直接將訂戶添加到事件中。 然后你可以安全地直接調用它。 因為總會有訂戶。

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

(注意,使用=直接賦值val => { }是一個Lambda表達式,它定義了一個空訂閱者。)

另外,如果你想做很多事件,請查看.netReactive Framework ,這是正確的解決方案。

這允許您從類中手動觸發事件。

這是提升內部事件的標准模式,這就是私有的原因。

OnOneSecond只是一個用於引發事件的輔助方法。 您可以使用沒有這些方法的事件,它只是一個已建立的模式,將if (Elapsed != null)檢查包裝在一個名稱以On開頭的方法中...

從技術上講,您可以使用Elapsed(source, args)而不是OnOneSecond(source, args) ,但如果沒有注冊偵聽器,則會拋出NullReferenceException

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM