質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

3回答

12289閲覧

EventArgsを継承したクラスを使用する意味はなんでしょうか?

退会済みユーザー

退会済みユーザー

総合スコア0

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

2クリップ

投稿2019/07/06 10:08

前提・実現したいこと

C#でイベントについて学習しています。

独自のEventArgsを使用する際に、色々なサンプルでEventArgsを継承すると書かれているのですが
継承が必要な理由がよくわかりません。
以下、TextBoxでXキーが押された際に実行されるイベントを作ってみました。

この際、XKeyDownArgsでEventArgsを継承してもしなくても挙動は変わらないように見えます。
EventArgsを継承することの利点や、しなければならない理由が何かあるのでしょうか?

よろしくおねがいします。

該当のソースコード

C#

1public partial class Form1 : Form 2{ 3 private event EventHandler<XKeyDownArgs> XKeyDown; 4 5 public Form1() 6 { 7 InitializeComponent(); 8 } 9 10 private void Form1_Load(object sender, EventArgs e) 11 { 12 XKeyDown += XKeyDownMessage; 13 } 14 15 private void TextBox1_KeyDown(object sender, KeyEventArgs e) 16 { 17 if (e.KeyCode == Keys.X) 18 { 19 XKeyDown?.Invoke(sender, new XKeyDownArgs()); 20 } 21 } 22 23 private void XKeyDownMessage(object sender, XKeyDownArgs e) 24 { 25 MessageBox.Show("Xキーが押されました"); 26 } 27} 28 29// EventArgsを継承してもしなくても問題なく動作する 30public class XKeyDownArgs : EventArgs 31{ 32}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

提示された例ですと
private event EventHandler<XKeyDownArgs> XKeyDown;
としているので、デリゲートの引数はXKeyDownArgsという型であればいいことになります。
ですが、EventArgsを継承している必要はありません。
ですが、EventArgsの説明を見ると

イベントのデータを含み、イベント データを含まないイベントに使用する値を提供するクラスの、基本クラスを表します。

とあります。
日本語があやしいですが、要は
イベントデータが必要な場合の基底クラスで、イベントデータを含まない場合の値ということです。
イベントデータとして渡す場合、EventArgsを継承するのはお約束だと思ってください。

では、EventArgsとは何なのかということですが、
これは「イベントの補足情報はありません。」ということを示すものです。

例のXKeyDownイベントは補足情報がありませんので本来は
private event EventHandler XKeyDown;
と定義し、EventArgsを渡すようにすべきです。

イベントハンドラでEventArgsが引数としてある場合、このイベントは補足情報がないというのが一目で分かるからです。
引数にEventArgs以外のクラスが来る場合(例の場合XKeyDownArgsクラス)はそのイベントに補足情報があると判断してしまうことになります。

投稿2019/07/06 11:08

YAmaGNZ

総合スコア10242

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/07/06 14:24

ご回答ありがとうございます。 丁寧なご説明で全体的に非常にわかりやすかったです。 イベントの理解が進みました。ありがとうございます。
guest

0

理由はお約束だからとしか言いようがありません。
メリットは基底クラスを引数にもつイベントハンドラを汎用的に使えるとかでしょうかね。

そういった細かい約束が、解りやすく不具合が出にくいプログラムを書くには
必要なことなのです。

投稿2019/07/06 10:41

hihijiji

総合スコア4150

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/07/06 14:25

ご回答ありがとうございます。 >メリットは基底クラスを引数にもつイベントハンドラを汎用的に使えるとかでしょうかね。 EventArgsというクラスがあることによって、補足情報がないイベントの場合には 誰が作ってもEventArgsをパラメータに使うことになる。 なので、+=できるメソッドのパラメータをEventArgsで統一する事ができる。 逆にEventArgsが無ければ個人個人が好きな型をパラメータにしてしまう可能性がある。 そうなると、+=できるメソッドのパラメータが個人個人でバラバラになってしまい 自分以外の人が作ったメソッドを+=できなくなるかもしれない。 こんな感じの認識であっていますでしょうか?
hihijiji

2019/07/09 03:01

単純に一つのイベントハンドラを複数のイベントで使いまわせるってだけです。 フレームワークによりますが
guest

0

すでに解決済のようですので今さらながらのレスですが、ちょっと気になったので一言・・・

EventArgsを継承することの利点や、しなければならない理由が何かあるのでしょうか?

イベントと共に何らかの情報をイベントハンドラに渡す場合に EventArgs を継承したカスタムクラスを作ることになります。

情報をイベントハンドラに渡さない場合は EventArgs クラスを使います。

では、情報を渡さないのに何故 Form1_Load(object sender, EventArgs e) というようにするのかという理由は、.NET Framework クラスライブラリ内のすべてのイベントは、次のように定義されている EventHandler デリゲートに基づいているからです。

public delegate void EventHandler(object sender, EventArgs e);

ユーザーが定義するカスタムクラスのイベントも、上記 .NET Framework のパターンに基づいて発行することが推奨されています。

詳しくは以下の記事が参考になると思います。

方法 : .NET Framework ガイドラインに準拠したイベントを発行する (C# プログラミング ガイド)
https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/events/how-to-publish-events-that-conform-to-net-framework-guidelines

記事のサンプルコードに EventArgs を継承したカスタムクラスの使い方が記載されているので見てください。

他に、イベントを起動する OnXxxx メソッドの使い方も書いてありますので、そのあたりも参考になると思います。

投稿2019/07/07 01:34

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/07/08 03:40

ご回答ありがとうございます。 Onメソッドの使い方とクラス外からのイベントの使い方の説明参考になりました。 ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問