イベント part1 (十週目の学習)

<font color="limegreen">モチベーションも大事だと思うので覚書として使用します。</font>
<font color="DarkSlateGray"><details><summary>十週目の感想</summary><div>今週は例外処理で少しずれ込みました、学習は仕様の確認だけにして、来週Versionアップしたつもりで頑張ろうと思います。。脳が休息を欲してる(気がした)のでこの期間にリフレッシュして緩めました♨

ちょうど十週間突破したので、何週間表示はやめようと思います。あと`既存`という字は`きそん`と本来いうらしいです。てことは`現存`は`げんそん`か…
</font></details></div>

---------------


#<font color="SlateGray">イベント
イベントは、GUI(ｸﾞﾗﾌｨｶﾙﾕｰｻﾞｲﾝﾀﾌｪｰｽ)におけるユーザ入力やクリックの事。
何が起こったら(イベント)どうする(イベントハンドラ)。

使用には、
①デリゲート
Delegateか中にAction(どちらもDelegate(メソッド参照))作る。
②イベントフィールド
最初のクラスをｲﾍﾞﾝﾄﾌｨｰﾙﾄﾞとする
(`event`宣言(先程のﾃﾞﾘｹﾞｰﾄを宣言のﾀｰｹﾞｯﾄにする(ｲﾍﾞﾝﾄﾊﾝﾄﾞﾗがあるメソッド呼び出し可能にするため)
と条件(if(EventName !=null)EventName(引数);)も作成)
③イベントハンドラ
2.3個目のクラスに呼び出すメソッド作成(ｲﾍﾞﾝﾄﾊﾝﾄﾞﾗ内容)
③Main
ｲﾍﾞ名 += new ﾃﾞﾘ名(実行ﾒｿｯﾄﾞ)
event発生時実行文`EventName();`
※呼出は抽象的ならオーバーライド(上書き)(引数同じ)メソッド使ってもいい




<details><summary><b>例外処理としてデリゲートで各メソッド呼び出して発生(本来トリガーif)</b></summary><div>

```c#:例外処理としてデリゲートで各メソッド呼び出して発生(本来トリガーif)

class MyEvent
{
    //public Action MyDelegate;
    public event MyDelegate EventName;

    public void OnEventName()
    {
        if (EventName != null)// null例外
            EventName();//ｲﾍﾞﾝﾄ発生
    }
}

class MyClass
{
    public void Show()
    {
        Console.Write(1);
    }
}

class MyClass2
{
    public void Show2()
    {
        Console.Write(2);
    }
}

class Event1
{
    public static void Main()
    {
        MyClass mc = new MyClass();
        MyClass2 mc2 = new MyClass2();
        MyEvent me = new MyEvent();

        // ｲﾍﾞﾝﾄﾊﾝﾄﾞﾗ
        me.EventName += new MyDelegate(mc.Show);
        me.EventName += new MyDelegate(mc2.Show2);
 　　　//me.EventName += () => mc2.Show2; λでスリム

        me.OnEventName();//ｲﾍﾞﾝﾄ発生
    }
}
```
</details></div>

<details><summary><b>クラスに分割してデリゲートでイベント(一桁加算機)</b></summary><div>

```c#:neko.kasanki.delegate
// 何かデリゲートの学習してるみたいだけど、元来のイベント処理手順がわかった。
using System;

// 1.delegate
delegate void Handler(char ch);
// 2.field
class EventClass
{
    public event Handler KeyHit;

    public void OnKeyHit(char ch)
    {
        if (KeyHit != null)
            KeyHit(ch);
    }
}
// 3.handler
class Show
{
    int sum = 0;

    public void KeyShow(char ch)
    {
        if (Char.IsDigit(ch))
        {
            int a = (int)char.GetNumericValue(ch);
            sum += a;
            Console.Write($"+{a}\n");
            Console.Write($"={sum}\n");
        }
        else if (ch == 'c')
        {
            sum = 0;
            Console.Write("合計がクリアされました\n");
        }
        else return;
    }
}
// 4.Main
class Event2
{
    public static void Main()
    {
        ConsoleKeyInfo cki;

        EventClass ec = new EventClass();
        Show s = new Show();

        ec.KeyHit += new Handler(s.KeyShow);

        while (true)
        {
            if (Console.KeyAvailable)
            {
                cki = Console.ReadKey(true);
                if (cki.KeyChar == 'x')
                    break;
                else ec.OnKeyHit(cki.KeyChar);
            }
        }
    }
}

```
</details></div>

<details><summary><b>(来週)クラスに分割してオーバーライドメソッドでイベント(一桁加算機)</b></summary><div>

```c#:neko.kasanki.override
// 何かデリゲートの学習してるみたいだけど、元来のイベント処理手順がわかった。

```
</details></div>

<font color="crimson">このようにｲﾍﾞﾝﾄﾊﾝﾄﾞﾗはﾕｰｻﾞｲﾍﾞﾝﾄを想定し、条件をﾄﾘｶﾞｰとして、ｲﾍﾞﾝﾄ時呼び出されます。</font>














<br>
##<font color="DimGray">コールバック</font>

処理呼出(コールバックだから呼戻し？)今までの学習内で5つ程ありました。

<b>[Ⅰ.普通にメソッド引数を渡す](https://qiita.com/h_okabe/items/8748bd9f401f36bae3a1#%E5%BC%95%E6%95%B0)</b>
処理メソッドに引数定義、①返す用のint w②代入`w=x+y`③返す用`return w`設定。
Main関数で①返される用の`int result`②渡す用の`result=渡したい関数名(引数の値)`③それを用いた処理文

<b>[Ⅱ.コンストラクタ](https://qiita.com/h_okabe/items/bd193ed005b2ca190c0d#%E3%82%AF%E3%83%A9%E3%82%B9%E3%81%AE%E7%B6%99%E6%89%BF%E3%81%A8%E3%82%B3%E3%83%B3%E3%82%B9%E3%83%88%E3%83%A9%E3%82%AF%E3%82%BF)</b>
 (クラス名と同じにする、Mainにて呼出時インスタンス化、Test test = new Test();)

<b>[Ⅲ.オーバーライド](https://qiita.com/h_okabe/items/bd193ed005b2ca190c0d#%E3%82%AA%E3%83%BC%E3%83%90%E3%83%BC%E3%83%A9%E3%82%A4%E3%83%89)</b>
(元ﾒｿｯﾄﾞを`public virtual~`として、派生ｸﾗｽ先は`public override~`このようにｵｰﾊﾞｰﾗｲﾄﾞﾒｿｯﾄﾞ作る)
(意味は上書き)(条件は引数同じ)
memo.処理内容`{return}`にしとけば派生先で元ﾒｿｯﾄﾞでも`{return}`でそのクラス処理文に対して`return`で返される。

 
<b>[Ⅳ.デリゲート](#イベント)</b>
①まずクラス外で宣言して 例`delegate void DeleName(int a, int b)`
②MainでデリゲートをNewインスタンス化か代入 例`new DeleName(c.Minus)`
③最後に引数代入と共に呼び出し 例`d1(2, 1)`

<b>[Ⅴ.抽象メソッド](https://qiita.com/h_okabe/items/bd193ed005b2ca190c0d#%E6%8A%BD%E8%B1%A1-abstract)</b>
(規格みたいな感じ、派生クラス作ってパーツ作れる)①abstract class～、public abstract int～、という風に2回つけて設定
②実装クラスのメソッドにはoverrideつける※基本クラス下の場合
<b>※[interface](https://qiita.com/h_okabe/items/c7aeeb452bdcbc9c51fe#%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%95%E3%82%A7%E3%82%A4%E3%82%B9-interface)…メソッドではなくクラスと同列階層だが、抽象メンバを呼び出す。当然派生クラス先でパーツ化する。
abstractの利用価値下がる(interfaceだと自由に継承や複数設定ができ汎用性ある`class名: interface1, interface2, ...`)

Ⅵ. ローカル関数 ←New!C#7
メソッドの中に書くメソッド

static void SampleMethod01()
{
// 親メソッドしかアクセス出来ないので修飾子いらない
  int LocalFunc01(int a, int b)
    => a + b;

  // ここより前で定義されているローカル関数の呼び出し
  WriteLine($"LocalFunc01(1,2)={LocalFunc01(1,2)}");
  // 出力：LocalFunc01(1,2)=3

※イベントアクセサやプロパティgetter、setterの本体で使える

```c#
Before:
public string FullName
{
    get
    {
        return FirstName + " " + LastName;
    }
}

// After:
public string FullName => FirstName + " " + LastName;
```


```c#
static void SampleMethod03()
{
  // ラムダ式でデリゲートを定義して使う従来の書き方
  Func<int, bool> IsOdd = (n) =>
    {
      return n % 2 != 0;
    };
  var odds = Enumerable.Range(1, 10).Where(IsOdd);
  WriteLine($"odds={string.Join(",", odds)}");
  // 出力：odds=1,3,5,7,9

  // ローカル関数も、通常のメソッドと同様にデリゲートとして扱える
  bool IsEven(int n)
  {
    return n % 2 == 0;
  }
  var even = Enumerable.Range(1, 10).Where(IsEven);
  WriteLine($"evens={string.Join(",", evens)}");
  // 出力：evens=2,4,6,8,10
}
```

ちなみにイベント呼出にはデリゲートとオーバーライドをよく見かけるのですが、
理由があるみたいなので試すのは端折りました。

------------------
次回は、オーバーライドで試してイベントプロパティやAction、Funcも確認したいと思います。
memo:発生頻度の低いイベントを数多く定義する場合は、[イベントプロパティ](https://docs.microsoft.com/ja-jp/dotnet/standard/events/how-to-handle-multiple-events-using-event-properties)