C#ではデリゲートを使用する際、通常は以下のようにデリゲート型を宣言します:
private delegate string GreetDelegate();
この例では、stringはデリゲートに適合するメソッドの戻り値型を示し、デリゲート名GreetDelegateにはパラメータがありません。
デリゲートに適合するメソッドを定義:
public static string GetGreetingMessage()
{
return "こんにちは";
}
呼び出し例:
static void Main(string[] args)
{
GreetDelegate greet = GetGreetingMessage;
Console.WriteLine(greet());
}
デリゲート変数を事前に宣言せずに使用するには、Funcデリゲートを活用します。
Funcデリゲートの基本
Func<TResult>:パラメータなしでTResult型を返すデリゲート
static void Main(string[] args)
{
Func<string> greet = GetGreetingMessage;
Console.WriteLine(greet());
}
Func<T, TResult>:1つの入力パラメータを受け取るデリゲート
Func<string, int> parser = ConvertToInteger;
public int ConvertToInteger(string input)
{
return int.Parse(input);
}
入力パラメータが増える場合は、Func<T1, T2, TResult>などのバリエーションを使用します。
匿名メソッドとの連携
public static void Main()
{
Func<string, int, string[]> segmenter = delegate(string text, int limit)
{
char[] delims = { ' ', ',', '.' };
return limit > 0 ? text.Split(delims, limit) : text.Split(delims);
};
string title = "こころ";
foreach (string word in segmenter(title, 3))
Console.WriteLine(word);
}
ラムダ式との連携
public static void Main()
{
char[] separators = { ' ' };
Func<string, int, string[]> segment = (s, i) =>
i > 0 ? s.Split(separators, i) : s.Split(separators);
foreach (string word in segment("羅生門", 2))
Console.WriteLine(word);
}
Actionデリゲート
戻り値がない場合(voidメソッド)はActionを使用:
static void Main(string[] args)
{
Action logger = WriteLog;
logger();
}
public static void WriteLog()
{
Console.WriteLine("ログを出力");
}
Action<T>:1つのパラメータを受け取るバージョン
static void Main(string[] args)
{
Action<string> logger = WriteMessage;
logger("処理完了");
}
public static void WriteMessage(string message)
{
Console.WriteLine(message);
}
ラムダ式との組み合わせ
static void Main(string[] args)
{
Action<string> simpleLogger = msg => Console.WriteLine(msg);
simpleLogger("簡易ログ出力");
}