跳過到頁腳內容
Iron Academy Logo
學習 C#
學習 C#

其他分類

理解 C# 事件

Tim Corey
1h 9m 13s

C# 中的事件是許多開發者使用但可能未完全了解的基本概念,尤其是在創建自己的事件時。 Tim Corey 提供了一個全面的指南,教您如何創建和使用事件,探討在影片"C# Events - Creating and Consuming Events in Your Application"中好的做法和進階功能。

在這篇文章中,我們將探討 C# 的事件,重點在於其語法,如何定義,以及如何利用 Tim Corey 的影片範例解決常見的程式問題。 理解 C# 中的事件處理對於建構響應式應用程式至關重要,這篇文章將幫助您掌握自訂錯誤日誌、異常處理以及事件驅動程式設計的核心概念。

事件介紹

在 C# 和程式語言中,事件在事件驅動程式設計中扮演著關鍵角色,使應用程式能夠響應使用者互動或系統變更等行動。 與其他程式語言相比,C# 提供一種結構化的方法來處理事件,這使其成為開發快速和小型應用程式的理想選擇。 C# 中的事件由具體行動觸發,這些行動調用相應的事件處理程式以執行預期的任務。

Tim 開始解釋大多數開發者對於 C# 中的事件都很熟悉,但可能不知道如何創建自訂事件。 這段影片的目標是介紹事件,逐步示範創建自訂事件,討論其功能,並概述最佳實踐。

演示應用程序走過

Tim 使用了一個由 Windows Forms (WinForms) 建置的簡單銀行應用程式來演示事件。 該應用程式模擬了一位客戶的基礎銀行操作,包括查看餘額和記錄交易。

  1. 應用程式概況

    • 該應用程式有兩個窗體:一個用於顯示帳戶餘額和交易,另一個用於記錄新交易。
    • 它包括模擬信用卡購物的按鈕,並通過從儲蓄轉移資金到支票來處理透支。
  2. 主窗體

    • 顯示客戶的姓名、支票和儲蓄帳戶餘額。
    • 顯示兩個帳戶的交易列表。
    • 包含一個按鈕以打開交易記錄窗體。
  3. 交易窗體

    • 允許用戶輸入交易金額。
    • 模擬購物並通過從儲蓄轉移資金到支票來處理透支。

示範應用程式背後的代碼

Tim 解釋了該示範銀行應用程式的後端代碼:

  1. 客戶類別

    • 表示一個客戶,具有客戶姓名和兩個帳戶(支票和儲蓄)的屬性。
    • 客戶類別很簡單,但它是理解如何管理多個帳戶的良好起點。
  2. 帳戶類別

    • 管理銀行帳戶的詳細信息,包括帳戶名稱、餘額和交易列表。
    • 餘額屬性是十進制型別,用於精確的貨幣計算。
    • 交易屬性是唯讀列表,以防止外部修改。
  3. 處理存款和付款

    • 新增存款方法:將存款新增到帳戶,更新餘額,並記錄交易。
    • 付款方法:處理提款,包括檢查是否有足夠的資金以及如果需要,通過從備用帳戶轉移資金來管理透支保護。
  4. 透支保護

    • 該應用程式包含處理透支的邏輯。 如果支票帳戶餘額不足以進行交易,應用程式會檢查儲蓄帳戶以補足不足之處。 如果合併餘額足夠,則將所需金額轉移到支票帳戶並完成交易。

要查看代碼示例,您可以直接參考 Tim Corey 的影片,他在從 3:18 到 18:27 解釋了代碼。

事件:按鈕點擊

在這一部分,Tim Corey 深入講解了 Windows Forms 中按鈕點擊事件的工作原理,解釋了這些事件是如何接線並如何工作。

了解按鈕點擊事件

Tim 開始解釋 Windows Forms 應用程式中按鈕點擊事件的熟悉概念。 當您在設計器中雙擊按鈕時,Visual Studio 會自動為點擊事件生成一個事件處理方法。

  1. 事件處理方法

    • 每當按鈕被點擊,這個方法就會被調用。 在這裡,您可以放置應該在按鈕點擊時運行的代碼。
    private void recordTransactionButton_Click(object sender, EventArgs e)
    {
       // Code to handle the button click event
    }
    private void recordTransactionButton_Click(object sender, EventArgs e)
    {
       // Code to handle the button click event
    }
  2. 接線事件

    • 事件處理方法是在窗體的設計器文件(FormName.Designer.cs)中接線到按鈕點擊事件的。 這是通過使用 += 符號將事件處理程式新增到按鈕的點擊事件中完成的。
    this.recordTransactionButton.Click += new System.EventHandler(this.recordTransactionButton_Click);
    this.recordTransactionButton.Click += new System.EventHandler(this.recordTransactionButton_Click);

創建和調用自訂事件

Tim 解釋如何在 C# 中創建自訂事件,從事件將被觸發的帳戶類別開始。

  1. 定義事件

    • 使用 event 關鍵字定義一個事件。 它看起來類似於公用變數,但專門用於事件。
    public event EventHandler<string> RaiseTransactionApprovedEvent;
    public event EventHandler<string> RaiseTransactionApprovedEvent;
  2. 觸發事件

    • 使用 Invoke 方法觸發事件,通常在定義事件的類別中。 Invoke 方法接受兩個參數:發送者(通常是 this)和事件數據(在此情況下為字串)。
    private void OnTransactionApproved(string transactionName)
    {
       RaiseTransactionApprovedEvent?.Invoke(this, transactionName);
    }
    private void OnTransactionApproved(string transactionName)
    {
       RaiseTransactionApprovedEvent?.Invoke(this, transactionName);
    }
  3. 接線和處理事件

    • 使用 += 符號訂閱事件,並定義一個在事件引發時處理它的方法。
    account.RaiseTransactionApprovedEvent += Account_RaiseTransactionApprovedEvent;
    
    private void Account_RaiseTransactionApprovedEvent(object sender, string e)
    {
       // Code to handle the event
    }
    account.RaiseTransactionApprovedEvent += Account_RaiseTransactionApprovedEvent;
    
    private void Account_RaiseTransactionApprovedEvent(object sender, string e)
    {
       // Code to handle the event
    }

使用事件更新 UI

Tim 解釋如何使用事件自動更新瀏覽器 UI 當某些動作發生時,例如交易核准時。

  1. 引發事件

    • 在交易核准後觸發自訂事件。
    public void AddDeposit(decimal amount, string depositName)
    {
       // Code to add deposit
       RaiseTransactionApprovedEvent?.Invoke(this, depositName);
    }
    public void AddDeposit(decimal amount, string depositName)
    {
       // Code to add deposit
       RaiseTransactionApprovedEvent?.Invoke(this, depositName);
    }
  2. 在 UI 中訂閱事件

    • 在主窗體中訂閱事件,以在新交易被核准時更新交易列表。
    public MainForm()
    {
       InitializeComponent();
       account.RaiseTransactionApprovedEvent += Account_RaiseTransactionApprovedEvent;
    }
    
    private void Account_RaiseTransactionApprovedEvent(object sender, string e)
    {
       // Update the UI with the new transaction
    }
    public MainForm()
    {
       InitializeComponent();
       account.RaiseTransactionApprovedEvent += Account_RaiseTransactionApprovedEvent;
    }
    
    private void Account_RaiseTransactionApprovedEvent(object sender, string e)
    {
       // Update the UI with the new transaction
    }

Event?.Invoke() 解釋

Tim Corey 解釋了在 C# 中引發事件時使用 ?.Invoke() 語法的用法。 這種現代方法簡化了代碼並可確保線程安全。

問號運算符

問號(?.)在 Invoke 之前是空條件運算符。 它在調用前檢查事件處理方法是否為 null,以防止潛在的異常。

  1. 傳統方法

    • 之前,開發者使用多行代碼來檢查事件處理方法是否為 null,然後調用它。
    if (RaiseTransactionApprovedEvent != null)
    {
       RaiseTransactionApprovedEvent(this, depositName);
    }
    if (RaiseTransactionApprovedEvent != null)
    {
       RaiseTransactionApprovedEvent(this, depositName);
    }
  2. 現代方法與 ?.Invoke():

    • 空條件運算符簡化了這個過程,在一行之內完成空檢查並調用事件。
    RaiseTransactionApprovedEvent?.Invoke(this, depositName);
    RaiseTransactionApprovedEvent?.Invoke(this, depositName);
    • 如果 RaiseTransactionApprovedEvent 是 null,則不繼續調用,從而避免任何異常。
  3. 優點

    • 簡化代碼:減少了安全調用事件所需的代碼量。
    • 線程安全:通過在一個步驟內檢查空值並調用事件來消除競態情況。

傾聽並編寫事件代碼

Tim 解釋如何在 Windows Forms 應用程式中監聽自訂事件並相應地更新 UI。

  1. 訂閱事件

    • 使用 += 符號訂閱自訂事件。
    customer.CheckingAccount.TransactionApprovedEvent += CheckingAccount_TransactionApprovedEvent;
    customer.CheckingAccount.TransactionApprovedEvent += CheckingAccount_TransactionApprovedEvent;
  2. 事件處理方法

    • 定義一個方法來處理事件。 此方法基於事件數據更新 UI。
    private void CheckingAccount_TransactionApprovedEvent(object sender, string e)
    {
       // Update the UI with the new transaction
       checkingTransactionsDataSource.DataSource = null;
       checkingTransactionsDataSource.DataSource = customer.CheckingAccount.Transactions;
       checkingBalanceLabel.Text = customer.CheckingAccount.Balance.ToString("C2");
    }
    private void CheckingAccount_TransactionApprovedEvent(object sender, string e)
    {
       // Update the UI with the new transaction
       checkingTransactionsDataSource.DataSource = null;
       checkingTransactionsDataSource.DataSource = customer.CheckingAccount.Transactions;
       checkingBalanceLabel.Text = customer.CheckingAccount.Balance.ToString("C2");
    }

創建自訂事件:事件實踐與回顧

Tim 展示了創建、引發和處理自訂事件的整個過程。

  1. 觸發事件

    • 在交易核准或餘額變化後,引發事件。
    private void OnTransactionApproved(string transactionName)
    {
       RaiseTransactionApprovedEvent?.Invoke(this, transactionName);
    }
    private void OnTransactionApproved(string transactionName)
    {
       RaiseTransactionApprovedEvent?.Invoke(this, transactionName);
    }
  2. 處理多個事件

    • 確保應用程式監聽多個事件,例如交易和餘額變化,以保持 UI 實時更新。
    public MainForm()
    {
       InitializeComponent();
       customer.CheckingAccount.TransactionApprovedEvent += CheckingAccount_TransactionApprovedEvent;
       customer.SavingsAccount.TransactionApprovedEvent += SavingsAccount_TransactionApprovedEvent;
    }
    
    private void SavingsAccount_TransactionApprovedEvent(object sender, string e)
    {
       // Update the UI with the new savings transaction
       savingsTransactionsDataSource.DataSource = null;
       savingsTransactionsDataSource.DataSource = customer.SavingsAccount.Transactions;
       savingsBalanceLabel.Text = customer.SavingsAccount.Balance.ToString("C2");
    }
    public MainForm()
    {
       InitializeComponent();
       customer.CheckingAccount.TransactionApprovedEvent += CheckingAccount_TransactionApprovedEvent;
       customer.SavingsAccount.TransactionApprovedEvent += SavingsAccount_TransactionApprovedEvent;
    }
    
    private void SavingsAccount_TransactionApprovedEvent(object sender, string e)
    {
       // Update the UI with the new savings transaction
       savingsTransactionsDataSource.DataSource = null;
       savingsTransactionsDataSource.DataSource = customer.SavingsAccount.Transactions;
       savingsBalanceLabel.Text = customer.SavingsAccount.Balance.ToString("C2");
    }
  3. 運行應用程式

    • Tim 代碼演示了如何基於由交易引發的事件自動更新 UI。

事件參數信息:偵錯

Tim 展示了如何偵錯事件並檢查隨事件傳遞的信息。

  1. 設置斷點

    • 在事件處理方法中設置斷點以檢查事件數據。
    private void CheckingAccount_TransactionApprovedEvent(object sender, string e)
    {
       // Breakpoint here
    }
    private void CheckingAccount_TransactionApprovedEvent(object sender, string e)
    {
       // Breakpoint here
    }
  2. 偵錯

    • 運行應用程式並執行同意來觸發事件。 在調試器中檢查事件參數。
    • sender 參數提供了引發事件的實體,e 參數包含了事件數據。

創建另一個自訂事件(透支事件)

Tim Corey 通過創建處理透支情況的另一個自訂事件來擴展示範。 這個事件將在透支發生時觸發,並通知用戶透支金額。

定義透支事件

Tim 開始在帳戶類別中為透支場景定義新事件:

  1. 事件宣告

    • 使用 event 關鍵字定義事件,並使用十進制型別傳遞透支金額。
    public event EventHandler<decimal> OverdraftEvent;
    public event EventHandler<decimal> OverdraftEvent;
  2. 觸發事件

    • 事件在透支成功發生的代碼部分中觸發。
    if (overdraftSuccessful)
    {
       OverdraftEvent?.Invoke(this, overdraftAmount);
    }
    if (overdraftSuccessful)
    {
       OverdraftEvent?.Invoke(this, overdraftAmount);
    }

在儀表板側訂閱透支事件

  1. 接線事件

    • 在儀表板窗體中訂閱透支事件。
    customer.CheckingAccount.OverdraftEvent += CheckingAccount_OverdraftEvent;
    customer.CheckingAccount.OverdraftEvent += CheckingAccount_OverdraftEvent;
  2. 處理事件

    • 定義一個事件處理方法,以在透支發生時顯示訊息。
    private void CheckingAccount_OverdraftEvent(object sender, decimal e)
    {
       errorMessage.Text = $"You had an overdraft protection transfer of {e:C2}";
       errorMessage.Visible = true;
    }
    private void CheckingAccount_OverdraftEvent(object sender, decimal e)
    {
       errorMessage.Text = $"You had an overdraft protection transfer of {e:C2}";
       errorMessage.Visible = true;
    }
  3. 觸發並顯示事件

    • 當透支發生時,事件觸發並更新 UI 以通知用戶。
    You had an overdraft protection transfer of $20.44

在多個地點監聽事件

Tim 解釋如何在多種語言和窗體中監聽同一事件,展示事件的多功能性。

  1. 在另一窗體上新增標籤

    • 在次級窗體上新增標籤以顯示透支訊息。
    <asp:Label ID="errorMessage" runat="server" Visible="false" />
    <asp:Label ID="errorMessage" runat="server" Visible="false" />
    HTML
  2. 訂閱事件

    • 在次級窗體中訂閱透支事件。
    customer.CheckingAccount.OverdraftEvent += SecondaryForm_OverdraftEvent;
    customer.CheckingAccount.OverdraftEvent += SecondaryForm_OverdraftEvent;
  3. 處理事件

    • 定義一個事件處理方法,在次級窗體上顯示透支訊息。
    private void SecondaryForm_OverdraftEvent(object sender, decimal e)
    {
       errorMessage.Visible = true;
    }
    private void SecondaryForm_OverdraftEvent(object sender, decimal e)
    {
       errorMessage.Visible = true;
    }
  4. 同時事件處理

    • Tim 展示事件可以在多個窗體中同時處理,確保應用程式的所有相關部分適當地回應事件。
    Both the main form and the secondary form display the overdraft message when the event is triggered.

從記憶體中移除事件監聽器

Tim 強調清理事件監聽器以防止記憶洩漏並確保應用程式性能的重要性。

  1. 取消訂閱事件

    • 在銷毀類別實例或關閉窗體之前,必須取消訂閱事件。
    customer.CheckingAccount.OverdraftEvent -= CheckingAccount_OverdraftEvent;
    customer.CheckingAccount.OverdraftEvent -= CheckingAccount_OverdraftEvent;

    為什麼這很重要

    • 未能取消訂閱事件可能會導致記憶洩漏,因為正在監聽事件的對象可能無法被正確地垃圾收集。
  2. 使用命名方法

    • 避免使用匿名函數作為事件處理方法,因為這使得從事件中取消訂閱變得困難。
    // Good practice: using named methods for event handlers
    // Good practice: using named methods for event handlers

泛型 EventHandler:為 T 傳遞類別

Tim Corey 解釋了通過事件傳遞數據的最佳實踐,特別是使用類別而非簡單數據類型(如字串或十進制)的好處。

為什麼要為事件數據使用類別

Tim 開始討論為什麼使用簡單數據類型較不常見,以及為什麼通常最好傳遞一個類別:

  1. 靈活性和可擴展性

    • 使用類別允許您在事件中傳遞多個相關聯的數據。 如果您需要稍後新增更多數據,只需擴展類別而無需更改事件的簽章。
  2. EventArgs 繼承

    • 雖然以前任何通過事件傳遞的對象必須從 EventArgs 繼承,但這已不再是必需的。 不過,從 EventArgs 繼承仍然有助於一致性和清晰性。

創建透支 EventArgs 類別

Tim 示範如何為透支事件創建自訂 EventArgs 類別。

  1. 定義類別

    • 創建一個從 EventArgs 繼承的新類別,並包含您想要透過事件傳遞的數據屬性。
    public class OverdraftEventArgs : EventArgs
    {
       public decimal AmountOverdrafted { get; private set; }
       public string MoreInfo { get; private set; }
    
       public OverdraftEventArgs(decimal amountOverdrafted, string moreInfo)
       {
           AmountOverdrafted = amountOverdrafted;
           MoreInfo = moreInfo;
       }
    }
    public class OverdraftEventArgs : EventArgs
    {
       public decimal AmountOverdrafted { get; private set; }
       public string MoreInfo { get; private set; }
    
       public OverdraftEventArgs(decimal amountOverdrafted, string moreInfo)
       {
           AmountOverdrafted = amountOverdrafted;
           MoreInfo = moreInfo;
       }
    }
  2. 在事件中使用類別

    • 更新事件宣言以使用自訂的 EventArgs 類別。
    public event EventHandler<OverdraftEventArgs> OverdraftEvent;
    public event EventHandler<OverdraftEventArgs> OverdraftEvent;
  3. 觸發事件

    • 在調用事件時傳遞自訂 EventArgs 類別的實例。
    OverdraftEvent?.Invoke(this, new OverdraftEventArgs(amountNeeded, "Additional info"));
    OverdraftEvent?.Invoke(this, new OverdraftEventArgs(amountNeeded, "Additional info"));

唯讀屬性的重要性

Tim 強調在 EventArgs 類別中使用唯讀屬性以防止事件數據的意外修改的重要性。

  1. 避免修改

    • 如果 EventArgs 類別中的屬性具有公用 setter,則任何事件處理方法都可以修改數據,這可能導致意外行為。
    • 使用私有 setter 並透過構造函數初始化屬性確保事件數據保持一致性。
  2. 問題範例

    • Tim 示範了在一個事件處理方法中修改事件數據如何影響其他處理方法,若屬性不是唯讀的。
    private void CheckingAccount_OverdraftEvent(object sender, OverdraftEventArgs e)
    {
       e.AmountOverdrafted = 1000; // This modification affects all handlers
    }
    private void CheckingAccount_OverdraftEvent(object sender, OverdraftEventArgs e)
    {
       e.AmountOverdrafted = 1000; // This modification affects all handlers
    }
  3. 解決方案

    • 使用私有 setter 並透過構造函數傳遞數據以使屬性唯讀。
    public decimal AmountOverdrafted { get; private set; }
    public string MoreInfo { get; private set; }
    public decimal AmountOverdrafted { get; private set; }
    public string MoreInfo { get; private set; }

何時使用 Public Set (59:29) 的例外情況

Tim Corey 突出了一個重要的例外情況,使用私有 setter 的規則對於事件數據屬性。 這一例外情況是當您需要允許事件監聽器修改事件數據時,例如在可能根據某些條件取消交易的情況下。

範例:取消交易

Tim 提供了一個範例,其中事件處理方法可能需要取消交易。 這是透過在自訂 EventArgs 類別中新增 CancelTransaction 屬性來實現的。

  1. 定義屬性

    • 在 EventArgs 類別中新增一個同時具有 getter 和 setter 的公用屬性。
    public class OverdraftEventArgs : EventArgs
    {
       public decimal AmountOverdrafted { get; private set; }
       public string MoreInfo { get; private set; }
       public bool CancelTransaction { get; set; } = false;
    
       public OverdraftEventArgs(decimal amountOverdrafted, string moreInfo)
       {
           AmountOverdrafted = amountOverdrafted;
           MoreInfo = moreInfo;
       }
    }
    public class OverdraftEventArgs : EventArgs
    {
       public decimal AmountOverdrafted { get; private set; }
       public string MoreInfo { get; private set; }
       public bool CancelTransaction { get; set; } = false;
    
       public OverdraftEventArgs(decimal amountOverdrafted, string moreInfo)
       {
           AmountOverdrafted = amountOverdrafted;
           MoreInfo = moreInfo;
       }
    }
  2. 在事件處理方法中設置屬性

    • 在儀表板中,事件處理方法可以設置此屬性以取消交易。
    private void CheckingAccount_OverdraftEvent(object sender, OverdraftEventArgs e)
    {
       if (denyOverdraft.Checked)
       {
           e.CancelTransaction = true;
       }
       errorMessage.Text = $"You had an overdraft protection transfer of {e.AmountOverdrafted:C2}";
       errorMessage.Visible = true;
    }
    private void CheckingAccount_OverdraftEvent(object sender, OverdraftEventArgs e)
    {
       if (denyOverdraft.Checked)
       {
           e.CancelTransaction = true;
       }
       errorMessage.Text = $"You had an overdraft protection transfer of {e.AmountOverdrafted:C2}";
       errorMessage.Visible = true;
    }
  3. 在源方法中檢查屬性

    • 在引發事件的方法中,檢查 CancelTransaction 屬性是否為 true 再繼續進行。
    if (args.CancelTransaction)
    {
       return false; // Transaction is canceled
    }
    if (args.CancelTransaction)
    {
       return false; // Transaction is canceled
    }

讓應用程式更具互動性

Tim 進一步優化應用程式,使其更具互動性和用戶友好性。

  1. 新增透支控制的複選框

    • 在窗體中新增一個複選框,允許用戶啟用或停用透支保護。
    private void InitializeComponent()
    {
       this.denyOverdraft = new System.Windows.Forms.CheckBox();
       // Initialize other controls
       this.denyOverdraft.Text = "Stop Overdrafts";
       this.denyOverdraft.CheckedChanged += new System.EventHandler(this.denyOverdraft_CheckedChanged);
    }
    private void InitializeComponent()
    {
       this.denyOverdraft = new System.Windows.Forms.CheckBox();
       // Initialize other controls
       this.denyOverdraft.Text = "Stop Overdrafts";
       this.denyOverdraft.CheckedChanged += new System.EventHandler(this.denyOverdraft_CheckedChanged);
    }
  2. 處理複選框狀態

    • 在複選框的事件處理方法中,在決定取消交易時更新邏輯以考慮到複選框狀態。
    private void denyOverdraft_CheckedChanged(object sender, EventArgs e)
    {
       if (denyOverdraft.Checked)
       {
           // Logic to stop overdraft transactions
       }
    }
    private void denyOverdraft_CheckedChanged(object sender, EventArgs e)
    {
       if (denyOverdraft.Checked)
       {
           // Logic to stop overdraft transactions
       }
    }
  3. 更新事件處理方法

    • 確保事件處理方法考慮複選框狀態以允許或拒絕透支。
    private void CheckingAccount_OverdraftEvent(object sender, OverdraftEventArgs e)
    {
       if (denyOverdraft.Checked)
       {
           e.CancelTransaction = true;
       }
       errorMessage.Text = $"You had an overdraft protection transfer of {e.AmountOverdrafted:C2}";
       errorMessage.Visible = true;
    }
    private void CheckingAccount_OverdraftEvent(object sender, OverdraftEventArgs e)
    {
       if (denyOverdraft.Checked)
       {
           e.CancelTransaction = true;
       }
       errorMessage.Text = $"You had an overdraft protection transfer of {e.AmountOverdrafted:C2}";
       errorMessage.Visible = true;
    }

總結

Tim Corey 通過總結工作 C# 事件的關鍵點和最佳實踐來結束教學。

  1. 移除事件監聽器

    • 始終在銷毀對象之前移除事件監聽器,以防止記憶洩漏。
    • 使用 -= 符號取消訂閱事件。
    customer.CheckingAccount.OverdraftEvent -= CheckingAccount_OverdraftEvent;
    customer.CheckingAccount.OverdraftEvent -= CheckingAccount_OverdraftEvent;
  2. 使用 EventArgs 繼承

    • 雖非必需,從 EventArgs 繼承有助於一致性,並使用內建功能如 EventArgs.Empty。
  3. 唯讀屬性的私有 Setter

    • 使用私有 setter 防止對事件數據的意外修改。 僅在必要時允許公用 setter,例如對於可取消的交易。
  4. 事件處理方法語法

    • 使用 EventHandler 委託來定義事件,提供一個明確一致的模式來傳遞事件數據。
  5. 空條件運算符

    • 使用空條件運算符(?.Invoke())來安全地調用事件,而不會冒 null 引用例外的風險。

結論

Tim Corey 的C# 事件綜合教程提供了寶貴的見解和實用的範例,幫助您有效地創建、處理和管理事件。 通過遵循這些最佳實踐,開發者可以創建更具互動性和響應性的應用程式。

Hero Worlddot related to 理解 C# 事件
Hero Affiliate related to 理解 C# 事件

通過分享您所愛的東西賺得更多

您是否在為使用.NET、C#、Java、Python或Node.js的開發者創建內容?將您的專業知識轉化為額外收入!

鋼鐵支援團隊

我們每週 5 天,每天 24 小時在線上。
聊天
電子郵件
打電話給我