Func<T, TResult>, Action<T> デリゲートの書式・利用方法 - C#

Func<T, TResult>, Action<T> デリゲートの書式や利用方法の紹介です。

概要

こちらの記事ではC#でのデリゲートの利用方法を紹介しました。
上記の記事のコードの記述方法で問題はありませんが、C# Version 2.0からは型パラメーターが導入されたため、デリゲートの宣言をよりシンプルに記述できるようになりました。

Func<T, TResult>

int型の引数を2つ持ち、戻り値をintで返す関数のデリゲートの宣言は以下のコードです。
delegate int SimpleFunc(int x, int y);
...
SimpleFunc func;

型パラメーターを用いた場合、上記のコードは以下のコードで記述できます。
Func<int,int,int> func;

型パラメーターを用いると関数の型ごとに型宣言をする必要がなくなり、シンプルで簡単にデリゲートを利用できます。反面、意味的な記述が失われるためコードの可読性が落ちる可能性もあります。

定義

Func(T, TResult)
の定義は以下となっています。
public delegate TResult Func<in T, out TResult>(
  T arg
)

定義されている型

Func<T, TResult> は引数の個数ごとに以下の定義があります。
  • Func(TResult)
  • Func(T, TResult)
  • Func(T1, T2, TResult)
  • Func(T1, T2, T3, TResult)
  • Func(T1, T2, T3, T4, TResult)
  • Func(T1, T2, T3, T4, T5, TResult)
  • Func(T1, T2, T3, T4, T5, T6, TResult)
  • Func(T1, T2, T3, T4, T5, T6, T7, TResult)
  • Func(T1, T2, T3, T4, T5, T6, T7, T8, TResult)
  • Func(T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult)
  • Func(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TResult)
  • Func(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TResult)
  • Func(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TResult)
  • Func(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, TResult)
  • Func(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult)
  • Func(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, TResult)
  • Func(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, TResult)
引数の数が16個までの型が定義されています。また、引数をとらず戻り値のみの型も定義されています。

Action<T>

戻り値が無い場合(void) の場合、Action を利用します。

定義

Action(T)
の定義は以下となっています。
public delegate void Action<in T>(
  T obj
)

定義されている型

Action<T, TResult>は引数の個数ごとに以下の定義があります。
  • Action(T)
  • Action(T1, T2)
  • Action(T1, T2, T3)
  • Action(T1, T2, T3, T4)
  • Action(T1, T2, T3, T4, T5)
  • Action(T1, T2, T3, T4, T5, T6)
  • Action(T1, T2, T3, T4, T5, T6, T7)
  • Action(T1, T2, T3, T4, T5, T6, T7, T8)
  • Action(T1, T2, T3, T4, T5, T6, T7, T8, T9)
  • Action(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)
  • Action(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11)
  • Action(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12)
  • Action(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13)
  • Action(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14)
  • Action(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15)
  • Action(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16)
Funcと同様に引数の数が16個までの型が定義されています。

サンプルプログラム

UI

以下のUIを作成します。テキストボックスとボタンを1つフォームに配置します。

コード

以下のコードを記述します。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace FuncDelegate
{
  public partial class FormMain : Form
  {
   
    public FormMain()
    {
      InitializeComponent();
    }
    
    public int AddFunc(int a, int b)
    {
      return a + b;
    }
    public int SubFunc(int a, int b)
    {
      return a - b;
    }

    private void button1_Click(object sender, EventArgs e)
    {
      Func<int, int, int> func = AddFunc;

      textBox1.Text += string.Format("{0:d}\r\n", func(5, 3));
      textBox1.Text += string.Format("{0:d}\r\n", func(2, 4));
      textBox1.Text += string.Format("{0:d}\r\n", func(3, 8));
      textBox1.Text += "----- \r\n";

      func = SubFunc;

      textBox1.Text += string.Format("{0:d}\r\n", func(6, 2));
      textBox1.Text += string.Format("{0:d}\r\n", func(8, 2));
      textBox1.Text += string.Format("{0:d}\r\n", func(3, 1));
    }
  }
}

解説

動作はこちらの記事で解説しているデリゲートの処理と同じ動作になっています。

実行結果

プロジェクトを実行します。下図のウィンドウが表示されます。

ボタンをクリックします。下図の結果が表示されます。


著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
掲載日: 2013-06-25
iPentec all rights reserverd.