C#の関数指向の仕組み

#ゆーじ勉強週間 3日目の記事です。

ほかの記事はこちら

 

今日の勉強テーマ

今日の勉強テーマは、「C#の関数指向の仕組み」です。

 

デリゲートラムダ式イベントなどについて勉強していきます。

勉強したことのメモのような感覚なので、上手くまとまってなかったりいろいろ飛ばしたりしてますがご了承ください。

 

昨日同様、こちらのサイトを参考にしました。
https://ufcpp.net/study/csharp/

デリゲート

デリゲートメソッドを参照する(代入する)ための変数の型

C#では、メソッドは他の型と同じように扱える。
変数に代入したり、引数や戻り値にしたり。

delegate int DelegateName(int x, int y);

先頭に「delegate」を記述し、普通のメソッドと同様に戻り値の型、デリゲート型名、引数を指定する。

using System;

// デリゲート型の定義
delegate void MyDelegate(int a);

class Sample
{
  void Main()
  {
    MyDelegate method = SampleMethod; // 暗黙にMyDelegate型に変換。
    method(256);
  }

  static void SampleMethod(int n)
  {
    Console.Write(n.ToString());
  }
}

マルチキャストデリゲート

+=演算子を用いることで、ひとつのデリゲート型変数に複数のメソッドを代入することができる。
その状態でデリゲートの呼び出し(実行)を行うと、代入された全てのメソッドが実行される。

マルチキャストデリゲート複数のメソッドを格納したデリゲート

デリゲートの非同期呼び出し

同期呼び出しメソッドを呼び出すと、そのメソッド内の処理が全て終わるまで呼び出し元には戻ってこない
非同期呼び出しメソッドを呼び出すと、そのメソッド内の処理を開始する一方で、呼び出し元の処理もそのまま並行して進んでいく

普通のInvoke()は同期呼び出し。
非同期呼び出しを使うには、BeginInvoke()を利用する。

MyDelegate async = new MyDelegate(MyMethod);

// 非同期で呼び出し
IAsyncResult asyncResult = async.BeginInvoke();

// この部分は並列実行
Console.Write("並列実行中");

// asyncの処理完了を待機
async.EndInvoke(asyncResult);

Console.Write("処理完了!");

asyncデリゲートに格納されたメソッドMyMethodの処理が重かった場合は、「並列実行中」が先に表示され、MyMethodの処理が終わった後に「処理完了」が表示される。

マルチキャストデリゲートの場合は非同期呼び出しできない。

ローカル関数

その場所でのみ使える関数。

void Main()
{
  // Main 関数の中で、ローカル関数 f を定義
  int f(int n) => n >= 1 ? n * f(n - 1) : 1;

  Console.WriteLine(f(10));
}

ラムダ式

メソッドを整数などの変数と同様に扱う手法。

(int n) => { return n > 0; };

のように{}の中身が単文のときは、returnと{}を省略して以下のように書くこともできる。

(int n) => n > 0;

イベント

イベントクリックなどのコンピュータ上で発生する事象。プロパティのデリゲート版。
イベントハンドライベントが発生した時に実行する処理
イベント駆動型イベントとイベントハンドラにより動作するプログラム

イベント発生側とイベント受取側の呼び方

イベント発生側source(イベント元)
observable(観測可能)
sender(送信者)
イベント受取側target(イベントの対象)
listener(聞き手)
handler(扱う人)
observer(観測者)
subscriber(購読者)
receiver(受信者)

イベントの宣言とイベントプロパティ

eventの宣言は以下。

event デリゲート型 イベント ハンドラー名;

 

イベントプロパティの記述は以下。

event デリゲート型 イベント ハンドラー名
{
  add
  {
    // イベントハンドラー追加時の処理を書く
  }
  remove
  {
    // イベントハンドラ削除時の処理を書く
  }
  // 追加/削除したいイベントハンドラは「value」に格納されている
}

拡張メソッド

既存のクラスにメソッドを追加できる。

第一引数のthisをつけた引数に自身が入る。

static class ColorExtensions
{
  public static Color SetAlpha(this Color c, float a){
    // 処理を記述
    Color tmp = c;
    tmp.a = a;
    return tmp;
  }
}

まとめ

今日はデリゲートやイベントを中心に勉強した。

実装までは行えなかったので、今度時間がある時にでも実際に実装して理解を深めたい。

 

次の記事

コメント