C#イベントを理解する
C#のイベントは、多くの開発者が使用する基本的な概念ですが、特に独自のイベントを作成する場合、完全に理解していない可能性があります。 ティム・コーリーは、"C# Events - Creating and Consuming Events in Your Application"というビデオで、ベストプラクティスと高度な機能を探求しながら、イベントの作成と使用方法について包括的なガイドを提供しています。
この記事では、ティム・コーリーのビデオ例を用いて、C#イベントの構文、定義方法、一般的なプログラミングの問題を解決する方法について説明します。 C#のイベント処理を理解することは、応答性の高いアプリケーションを構築するために不可欠であり、この記事は、カスタムエラーログ、例外処理、イベント駆動型プログラミングの中核となる概念を把握するのに役立ちます。
イベントの紹介
C#やプログラミング言語では、イベントはイベント駆動型プログラミングにおいて重要な役割を果たし、アプリケーションはユーザーとの対話やシステムの変更などのアクションに応答できるようになります。 他のプログラミング言語と比較して、C#はイベントの処理に構造化されたアプローチを提供し、高速なアプリケーションにも小規模なアプリケーションにも理想的です。 C#のイベントは特定のアクションによってトリガーされ、これらのアクションは対応するイベントハンドラを呼び出して目的のタスクを実行します。
Timはまず、ほとんどの開発者はC#のイベントに精通しているが、カスタムイベントの作成方法を知らないかもしれないと説明する。 ビデオのゴールは、イベントを紹介し、カスタムイベントの作成方法を説明し、その機能について説明し、ベストプラクティスの概要を説明することです。
デモ アプリケーション ウォークスルー
Timは、Windowsフォーム(WinForms)で構築されたシンプルな銀行アプリケーションを使用して、イベントのデモンストレーションを行います。 このアプリケーションは、残高の表示や取引の記録など、ある顧客の基本的な銀行業務をシミュレートするものです。
1.アプリケーションの概要:
- アプリケーションには、口座残高と取引を表示するフォームと、新規取引を記録するフォームの2つがあります。
- クレジットカードの購入をシミュレートするボタンや、普通預金から当座預金に資金を移動して当座借越を処理するボタンが含まれています。
2.メインフォーム:
- 顧客の名前、当座預金および普通預金の口座残高を表示します。
- 両口座の取引リストを表示します。
- 取引記録フォームを開くためのボタンが含まれています。
3.トランザクションフォーム:
- ユーザーが取引金額を入力できるようにします。
- 買い物のシミュレーションや、普通預金から当座預金への資金移動による当座借越の処理。
デモアプリの背後にあるコード
Timは、デモ・バンキング・アプリケーションのバックエンド・コードを説明しています:
1.顧客クラス:
- 顧客の名前と2つの口座(当座預金と普通預金)のプロパティを持つ顧客を表します。
- Customerクラスはシンプルですが、複数のアカウントを管理する方法を理解するための良い出発点となります。
2.アカウントクラス:
- 口座名、残高、取引リストなど、銀行口座の詳細を管理します。
- Balanceプロパティは、正確な金額計算のために10進数型です。
- Transactions プロパティは、外部からの変更を防ぐため、読み取り専用のリストです。
3.預金と支払いの処理:
- AddDepositメソッド:口座に預金を追加し、残高を更新し、トランザクションを記録します。
- MakePaymentメソッド: 十分な資金があるかどうかをチェックし、必要であればバックアップ口座から資金を移動することによって当座貸越保護を管理するなど、引き出しを処理します。
4.オーバードラフト保護:
- アプリケーションには、当座貸越を処理するロジックが含まれています。 当座預金口座の残高が取引に不足する場合、アプリケーションは不足分を補うために普通預金口座をチェックします。 合算残高が十分であれば、必要な金額を当座預金口座に振り込み、取引を完了する。
コードサンプルについては、ティム・コーリーが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.Wiring Up the Event:
イベント・ハンドラ・メソッドは、フォームのデザイナー・ファイル(FormName.Designer.cs)のボタン・クリック・イベントに配線されています。 これは、ボタンのクリックイベントにイベントハンドラを追加するために、+=演算子を使用して行われます。
this.recordTransactionButton.Click += new System.EventHandler(this.recordTransactionButton_Click);this.recordTransactionButton.Click += new System.EventHandler(this.recordTransactionButton_Click);
カスタム イベントの作成と呼び出し
Timは、イベントがトリガーされるAccountクラスから始めて、C#でカスタムイベントを作成する方法を説明します。
1.イベントの定義:
イベントは、event キーワードを使用して定義されます。 パブリック変数に似ていますが、イベント専用です。
public event EventHandler<string> RaiseTransactionApprovedEvent;public event EventHandler<string> RaiseTransactionApprovedEvent;
2.イベントのトリガー:
イベントは、通常、イベントを定義するクラス内で、Invokeメソッドを使用してトリガーされます。 Invokeメソッドは2つのパラメータを受け取ります:送信者(通常
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 }
イベント?.Invoke() の説明
Tim Coreyは、C#でイベントを発生させる際の?.Invoke()構文の使用について説明しています。 この現代的なアプローチは、コードを簡素化し、スレッドの安全性を保証します。
疑問符演算子について
Invokeの前のクエスチョンマーク(? イベントハンドラを呼び出す前に、NULLかどうかをチェックし、例外が発生する可能性を防ぎます。
1.従来のアプローチ:
以前は、開発者はイベントハンドラがNULLかどうかをチェックし、それを呼び出すために何行ものコードを使用していました。
if (RaiseTransactionApprovedEvent != null) { RaiseTransactionApprovedEvent(this, depositName); }if (RaiseTransactionApprovedEvent != null) { RaiseTransactionApprovedEvent(this, depositName); }
2.最新のアプローチ ?.Invoke():
null-conditional演算子は、このプロセスを合理化し、nullチェックを実行し、イベントを1行で呼び出します。
RaiseTransactionApprovedEvent?.Invoke(this, depositName);RaiseTransactionApprovedEvent?.Invoke(this, depositName);RaiseTransactionApprovedEventがnullの場合、呼び出しは進行しないため、例外を回避します。
3.メリット:
- コードの簡素化:イベントを安全に呼び出すために必要なコードの量を減らします。
- スレッドセーフ:nullをチェックし、単一ステップでイベントを呼び出すことによって、競合状態を排除します。
イベントの聴講とコードの記述
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 は、当座借越のシナリオのために Account クラスで新しいイベントを定義することから始めます:
1.イベント宣言:
イベントを定義するには、event キーワードと 10 進数型を使用して、当座貸越額を渡します。
public event EventHandler<decimal> OverdraftEvent;public event EventHandler<decimal> OverdraftEvent;
2.イベントのトリガー:
イベントは、オーバードラフトが正常に発生したコードの部分でトリガーされます。
if (overdraftSuccessful) { OverdraftEvent?.Invoke(this, overdraftAmount); }if (overdraftSuccessful) { OverdraftEvent?.Invoke(this, overdraftAmount); }
ダッシュボード側での当座貸越イベントの購読
1.Wiring Up the Event:
ダッシュボードのフォームでオーバードラフトイベントを購読する。
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 のクラスを渡す
ティム・コリーは、イベントを通してデータを渡すためのベストプラクティス、特に文字列や10進数のような単純なデータ型ではなくクラスを使用することの利点について説明しています。
なぜイベントデータにクラスを使うのか
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クラスのプロパティにパブリック・セッターがある場合、どのイベント・ハンドラもデータを変更することができ、予期しない動作につながる可能性があります。
- プライベート・セッターを使用し、コンストラクターを通してプロパティを初期化することで、イベント・データの一貫性を保つことができます。
2.問題の例:
Timは、プロパティが読み取り専用でない場合、1つのイベントハンドラでイベントデータを変更すると、他のハンドラに影響を与える可能性があることを示します。
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.ソリューション:
プロパティを読み取り専用にするには、プライベート・セッターを使用し、コンストラクタを通してデータを渡します。
public decimal AmountOverdrafted { get; private set; } public string MoreInfo { get; private set; }public decimal AmountOverdrafted { get; private set; } public string MoreInfo { get; private set; }
パブリックセットを使用する際の例外 (59:29)
ティム・コリーは、イベントデータ・プロパティにプライベート・セッターを使用するというルールの重要な例外を強調しています。 この例外は、特定の条件に基づいてトランザクションがキャンセルされる場合など、イベントリスナーがイベントデータを変更できるようにする必要がある場合です。
例トランザクションをキャンセルする
Timは、イベントハンドラがトランザクションをキャンセルする必要がある場合の例を示します。 これは、カスタムEventArgsクラスにCancelTransactionプロパティを追加することで実現されます。
1.プロパティの定義:
EventArgsクラスにゲッターとセッターの両方を持つパブリック・プロパティを追加します。
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 }
アプリケーションをよりインタラクティブにする
ティムは、よりインタラクティブでユーザーフレンドリーなアプリケーションにさらに磨きをかけます。
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.読み取り専用プロパティのプライベート・セッター:
- イベント・データの意図しない変更を防ぐために、プライベート・セッターを使用してください。 キャンセル可能なトランザクションなど、必要な場合にのみパブリック・セッターを許可してください。
4.イベントハンドラ構文:
- イベントを定義するためにEventHandlerデリゲートを使用して、イベントデータを渡すための明確で一貫したパターンを提供してください。
5.無条件演算子:
- ヌル条件演算子(?.Invoke())を使用して、ヌル参照例外のリスクを負うことなくイベントを安全に呼び出します。
結論
Tim Corey の C# events に関する包括的なチュートリアルでは、イベントを効果的に作成、処理、および管理するための貴重な洞察と実践的な例を提供しています。 これらのベストプラクティスに従うことで、開発者はよりインタラクティブで応答性の高いアプリケーションを作成することができます。

