こんにちは。明月です。
この投稿はC#でのイベント(event)キーワードを使い方に関する説明です。
プログラム言語ではイベント(event)の意味ではユーザの行動あるいはプログラム的にはアクションが発生する時、実行される関数という意味です。
つまり、ウィンドウフォームでボタンがある場合、ユーザがボタンをクリックすると実行される関数という意味です。
using System;
using System.Windows.Forms;
namespace Example
{
// Window formクラスを継承
class Program : Form
{
// シングルスレッド設定
[STAThread]
static void Main(string[] args)
{
// Programクラスのインスタンスを生成
Program p = new Program();
// Buttonクラスのインスタンスを生成
Button btn = new Button();
// Buttonのテキスト設定
btn.Text = "Button";
// ボタンをクリックするとデリゲートによりButtton_Click関数が呼び出す。
btn.Click += Buttton_Click;
// ウィンドウフォームのインスタンスにボタンのインスタンスを追加
p.Controls.Add(btn);
Application.Run(p);
}
// ボタンをクリックすると実行するイベント関数
private static void Buttton_Click(object sender, EventArgs e)
{
// メッセージボックス出力
MessageBox.Show("Hello");
}
}
}
上の例では簡単なウィンドウフォームを作成しました。
実行するとボタンがあるウィンドウフォームが生成されますが、ここでボタンをクリックするとButtton_Click関数が呼び出して実行されます。
こんなアクションをイベントと言います。
我々が以前の投稿で似ている機能に関して、デリゲート(delegate)で説明したことがあります。
link - [C#] 23. デリゲート(delegate)
using System;
namespace Example
{
// コンソールコマンドクラス
class ConsoleCmmand
{
// デリゲート生成
public delegate void PrintDelegate(string str);
// デリゲートリスト
public PrintDelegate list;
// コンストラクタ
public ConsoleCmmand()
{
// 無限ループ
while (true)
{
// コンソール出力
Console.Write("Command? ");
// ユーザから文字列を受け取る。
String cmd = Console.ReadLine();
// デリゲートに登録された関数を実行
list(cmd);
// もし、ユーザから受け取った文字列がexitなら
if ("EXIT".Equals(cmd, StringComparison.OrdinalIgnoreCase))
{
// 無限ループ終了
break;
}
}
}
}
class Program
{
// 実行関数
static void Main(string[] args)
{
// コンソールコマンドクラスのインスタンスを生成
ConsoleCmmand c = new ConsoleCmmand();
// イベント登録
c.list += Print_Event;
// 任意のキーを押してください
Console.WriteLine("Press any key...");
Console.ReadLine();
}
// ユーザから入力を受け取ったらイベント発生。
static void Print_Event(string str)
{
// コンソール出力
Console.WriteLine("Echo - " + str);
Console.WriteLine();
}
}
}
上のソースはコンソールからユーザで入力イベントを受け取ったらPrint_Event関数を発生します。
ここまでみるとデリゲートだけでイベント関数を実装しました。
ここまでだけでもイベント関数を実装することでは問題がありませんが、実はここにはオブジェクト指向プログラミング(OOP)のルール違反があります。
それがConsoleCmmandのデリゲートリストです。
上のデリゲートの呼び出しをコンストラクタ中でユーザから入力が発生すると実行する役割です。
でも、このリストがpublicで設定されているので、list("")形式でMain関数でも実行できることが欠点があります。
つまり、外部からはイベント関数を連結することが可能にしますが、実行はできないようにするべきです。
それがeventキーワードです。
using System;
namespace Example
{
// コンソールコマンドクラス
class ConsoleCmmand
{
// デリゲート生成
public delegate void PrintDelegate(string str);
// デリゲート
public PrintDelegate list;
}
class Program
{
// 実行関数
static void Main(string[] args)
{
// インスタンスを生成
ConsoleCmmand c = new ConsoleCmmand();
// イベント登録
c.list += Print_Event;
// デリゲート実行
c.list("Hello world");
// 任意のキーを押してください
Console.WriteLine("Press any key...");
Console.ReadLine();
}
// コンソール出力イベント
static void Print_Event(string str)
{
// コンソール出力
Console.WriteLine(str);
Console.WriteLine();
}
}
}
上の例をみればMain関数でデリゲートを実行しました。実はこんなことになるとクラス中で縛っているイベントが外部から強制(?)に実行される問題があります。
それならデリゲートの前でイベント付けたらどのようになるか?
using System;
namespace Example
{
// コンソールコマンドクラス
class ConsoleCmmand
{
// デリゲート生成
public delegate void PrintDelegate(string str);
// デリゲート
public event PrintDelegate list;
}
class Program
{
// 実行関数
static void Main(string[] args)
{
// インスタンスを生成
ConsoleCmmand c = new ConsoleCmmand();
// イベント登録
c.list += Print_Event;
// デリゲート実行
c.list("Hello world");
// 任意のキーを押してください
Console.WriteLine("Press any key...");
Console.ReadLine();
}
// コンソール出力イベント
static void Print_Event(string str)
{
// コンソール出力
Console.WriteLine(str);
Console.WriteLine();
}
}
}
コンパイル段階でエラーが発生しました。
つまり、イベントの関数を外部で付けることは可能ですが、実行はクラス中だけで実行することが可能です。
using System;
namespace Example
{
// コンソールコマンドクラス
class ConsoleCmmand
{
// デリゲート生成
public delegate void PrintDelegate(string str);
// デリゲート
public event PrintDelegate list;
// イベント実行関数
public void Execute()
{
// イベント実行
list("Execute");
}
}
class Program
{
// 実行関数
static void Main(string[] args)
{
// インスタンスを生成
ConsoleCmmand c = new ConsoleCmmand();
// イベント登録
c.list += Print_Event;
// イベント実行
c.Execute();
// 任意のキーを押してください
Console.WriteLine("Press any key...");
Console.ReadLine();
}
// コンソール出力イベント
static void Print_Event(string str)
{
// コンソール出力
Console.WriteLine(str);
Console.WriteLine();
}
}
}
要約すればイベント関数は以前のデリゲートから実行を我部で実行できないためのキーワードです。
ここまでC#でのイベント(event)キーワードを使い方に関する説明でした。
ご不明なところや間違いところがあればコメントしてください。
- [C#] 32. ジェネリックタイプ(Generic Type)を使い方2019/07/18 22:50:16
- [C#] 31. アトリビュート(Attribute)を使い方2019/07/18 20:22:16
- [C#] 30. Linq関数式を使う方法2019/07/17 23:06:42
- [C#] 29. Linqクエリ式を使い方2019/07/17 20:57:00
- [C#] 28. リスト(List)とディクショナリ(Dictionary)、そしてLinq式を使い方2019/07/16 22:40:03
- [C#] 27. varキーワードとdynamicキーワード2019/07/16 20:41:27
- [C#] 26. 例外処理(try ~ catch)する方法2019/07/16 00:59:34
- [C#] 25. イベント(event)キーワードを使い方2019/07/16 00:48:03
- [C#] 24. ラムダ式(匿名関数)とAction、Func関数を使い方、そしてクロージャ(Closure)2019/07/16 00:36:19
- [C#] 23. デリゲート(delegate)2019/07/15 02:25:26
- [C#] 22. インデクサー(indexer)を使う方法2019/07/13 01:06:04
- [C#] 21. C#のプロパティ(Property)2019/07/13 00:56:20
- [C#] 20. オブジェクト指向プログラミング(OOP)の4つの原則(カプセル化、抽象化、継承化、多相化(ポリモーフィズム))2019/07/12 00:17:35
- [C#] 19. 列挙型(enum)を使う方法2019/07/11 23:13:25
- [C#] 18. 構造体(Struct)、そして値型を参照するタイプ(Reference of value type)と参照型を参照するタイプ(Reference of reference type)2019/07/10 23:57:25
- check2024/04/10 19:03:53
- [Java] 64.Spring bootとReactを連結する方法(Buildする方法)2022/03/25 21:02:18
- [Javascript] Node.jsをインストールしてReactを使う方法2022/03/23 18:01:34
- [Java] 63. Spring bootでcronスケジューラとComponentアノテーション2022/03/16 18:57:30
- [Java] 62. Spring bootでWeb-Filterを設定する方法(Spring Security)2022/03/15 22:16:37
- [Java] JWT(Json Web Token)を発行、確認する方法2022/03/14 19:12:58
- [Java] 61. Spring bootでRedisデータベースを利用してセッションクラスタリング設定する方法2022/03/01 18:20:52
- [Java] 60. Spring bootでApacheの連結とロードバランシングを設定する方法2022/02/28 18:45:48
- [Java] 59. Spring bootのJPAでEntityManagerを使い方2022/02/25 18:27:48
- [Java] 58. EclipseでSpring bootのJPAを設定する方法2022/02/23 18:11:10
- [Java] 57. EclipseでSpring bootを設定する方法2022/02/22 19:04:49
- [Python] Redisデータベースに接続して使い方2022/02/21 18:23:49
- [Java] Redisデータベースを接続して使い方(Jedisライブラリ)2022/02/16 18:13:17
- [C#] Redisのデータベースを接続して使い方2022/02/15 18:46:09
- [CentOS] Redisデータベースをインストールする方法とコマンドを使い方2022/02/14 18:33:07