C#では、メソッドを関数のパラメータとして渡すことができ、コードの柔軟性と再利用性を大幅に向上させます。この機能は、コールバック、イベントハンドラ、および実行時の動作が特定のアクションを決定する戦略的なパターンを実装する上で不可欠です。この記事では、カスタムデリゲート、Func<>
、Action<>
に焦点を当て、これを実現するための様々なアプローチを探ります。
目次
メソッドをパラメータとして渡すためのカスタムデリゲートの使用
C#のデリゲートは、型安全な関数ポインタとして機能します。カスタムデリゲートを作成すると、メソッドのシグネチャが組み込みのFunc<>
またはAction<>
デリゲートと異なる場合に、きめ細かい制御と明確性を得ることができます。数値に対して演算を実行し、その結果を表示する関数について考えてみましょう。ここで、演算自体がパラメータとなります。
// カスタムデリゲートを定義
public delegate double MathOperation(double x);
public class Example
{
public static void PerformOperationAndPrint(double num, MathOperation operation)
{
double result = operation(num);
Console.WriteLine($"Result: {result}");
}
public static double Square(double x) => x * x;
public static double Cube(double x) => x * x * x;
public static void Main(string[] args)
{
PerformOperationAndPrint(5, Square); // 出力: Result: 25
PerformOperationAndPrint(5, Cube); // 出力: Result: 125
}
}
MathOperation
は、double
型を受け取りdouble
型を返すメソッドを表すデリゲートとして機能します。PerformOperationAndPrint
はこのデリゲートを受け入れるため、Square
、Cube
、またはその他の準拠するメソッドを使用できます。
Func<>
デリゲートの活用
Func<>
は、ゼロ個以上の入力パラメータと戻り値を持つメソッドを表すジェネリックデリゲートです。その組み込みの性質により、多くのシナリオが簡素化されます。前の例をリファクタリングしてみましょう。
public class Example
{
public static void PerformOperationAndPrint(double num, Func<double, double> operation)
{
double result = operation(num);
Console.WriteLine($"Result: {result}");
}
public static double Square(double x) => x * x;
public static double Cube(double x) => x * x * x;
public static void Main(string[] args)
{
PerformOperationAndPrint(5, Square); // 出力: Result: 25
PerformOperationAndPrint(5, Cube); // 出力: Result: 125
}
}
これにより、少ないコードで同じ結果が得られます。Func<double, double>
は、double
型を受け取りdouble
型を返すメソッドを指定します。ジェネリック型パラメータは、様々なメソッドシグネチャ(例:Func<int, string>
)に適応します。
Action<>
デリゲートの利用
Action<>
は、ゼロ個以上の入力パラメータとvoid
戻り値型(戻り値なし)を持つメソッドのためのジェネリックデリゲートです。メソッドが値を返さない場合に使用します。
public class Example
{
public static void PerformAction(string message, Action<string> action)
{
action(message);
}
public static void PrintMessage(string msg) => Console.WriteLine(msg);
public static void PrintMessageToUpper(string msg) => Console.WriteLine(msg.ToUpper());
public static void Main(string[] args)
{
PerformAction("Hello, world!", PrintMessage); // 出力: Hello, world!
PerformAction("Hello, world!", PrintMessageToUpper); // 出力: HELLO, WORLD!
}
}
Action<string>
は、文字列を受け取り何も返さないメソッドを表します。PerformAction
はこれを使用して、様々な印刷アクションを実行します。
結論
メソッドをパラメータとして渡すことは、強力なC#機能です。カスタムデリゲートは最大限の制御を提供する一方、Func<>
とAction<>
は便利な組み込みソリューションを提供します。最適なアプローチは、アプリケーションの特定の要件によって異なります。これらの技術を習得することは、より適応性が高く保守しやすいC#コードを作成するための鍵となります。