音ゲー、fps、DTM、プログラミング雑記置き場

ブログタイトル通りに雑記を垂れ流す。

【C#】デリゲート(delegate)を理解したい #1

  • 実用性がどうとかはおいといて、C#でデリゲートのイメージを
    なんとなくつかむための記事というよりC#初学者の苦悶雑記

デリゲートとは

  • メソッドのポインタ情報を格納する参照型変数
    • 他言語だとポインタ関数にあたるが、C#のデリゲートは複数メソッドの参照を同一デリゲートで管理できる(マルチキャスティング)

イベントハンドラとの関係性

  • デリゲートの性質より複数メソッドを管理できるため、
    クリックイベント(OnClick)に対し 複数コントロールを紐づけるような
    実装をする際に「どのコントロールがクリックされたか」の情報をデリゲートの引数で
    受け付けることで実装可能
    • MVCモデルのControllerみたいなことをデリゲートが担う
様々なInput(ユーザがクリックやマウスホバーなどの操作を行う)
    ┗ デリゲート「KewDown」 ━ 「a」キーが押された
                              ┗「b」キーが押された
                            ┗「c」キーが押された
  • 下記はイベントデリゲートを用いてイベントハンドラを発火させるサンプルコード
    • デリゲート自体はメソッドの参照するクラス(System.Delegate)なので
      Newやラムダ式によるインスタンス作成が必要
      • ラムダ式は内部でデリゲートとして扱われる
    • 1デリゲート-Nイベントの認識なので改良の余地あり
using System;

namespace ConsoleApp1 
{
    class Program
    {
        public delegate void KeyDownEventHandler();
        static public event KeyDownEventHandler A_keyDown;
        static void Main() 
        {
            String pressKey;
            EventHandler eh = new EventHandler();
            //イベントデリゲートにイベントハンドラを紐づける
            A_keyDown += new KeyDownEventHandler(eh.A_keyClick);
            //キー入力を受け付ける
            pressKey = Console.ReadKey().Key.ToString();
            //キー入力情報をイベントデリゲート経由でイベントハンドラを発火させる
            switch (pressKey) 
            {
                case "A":
                    A_keyDown();
                    break;
            }
        }
    }

    //イベントハンドラを管理するクラス
    class EventHandler 
    {
        public void A_keyClick() => Console.WriteLine("[A]key Pressed");
    }
}

あとがき

  • デリゲート引数受け取ってないじゃん、イベントハンドラ一つじゃんとか
    突っ込みどころは多いがひとまずこれで妥協
  • デリゲートのインスタンス生成が必要だったり等、デリゲートというよりC#
    性質を少しは理解できた気がする
  • サンプルソース改善版の#2はモチベがあったら書く