この記事は、C#で使われる「Invokeメソッド」についての基本的な使い方からなぜ使われるのかといったところを整理したものです。
C#を初めて触ったり、静的言語を扱ってこなかった人にはあまり馴染みのないメソッドかもしれません。
私もPHPの歴が長く初めて見た時に理解があまりできなかったのでここで自分の整理も含めて紹介したいと思います。
原理・仕組みをしっかり理解したい方にわかりやすく紹介しているのでそのような方におすすめです。
※自分も完璧に理解しているとは言えないのでもし間違い等ありましたら、ご指摘ください。
この記事を読むメリット
- C#のInvokeメソッドについて基本が理解できる
- なぜInvokeメソッドを使うのかメリットを理解できる
Invokeメソッドを初めて見た
私はC#の経験がなく、実務で初めてInvokeメソッドを目にしました。
以下のような形で実装されているコードをみました。
void ProcessWithLogging(string fileName, Action<string> action)
{
Console.WriteLine($"[{fileName}] 処理開始");
action.Invoke(fileName);
Console.WriteLine($"[{fileName}] 処理終了");
}
呼び出し側でのコードはこんな感じ。
ProcessWithLogging("report.pdf", (file) => {
// アップロード処理
Console.WriteLine($"{file} をアップロードします");
UploadFile(file);
});
軽く調べてみると、「関数を引数として渡す」ことで呼び出しがわで柔軟に実装ができるためにInvokeを使うということでした。
なんとなく理解はできましたが、別に引数で渡さず、別関数化したり条件分岐で処理分けるで良いのではと思ったので、Invokeについてしっかり理解をしようと思いました。
使うことによるメリットを理解した上で自分のものにして実際に使えるようになりたいと思い詳しく調べてみました。
エンジニアにおすすめ書籍
エンジニアになりたて、これから勉強を深めていきたいという方におすすめの書籍はこちら!
Invokeメソッドの基本
まずはInvokeメソッドの基本からです。
C#は、関数を引数として受け取ることができます。
その際引数としてdelegate型やAction、Funcなどを受け取ることができます。
void Execute(Action action)
{
Console.WriteLine("処理前");
action.Invoke(); // 渡された関数を実行
Console.WriteLine("処理後");
}
その際、「Invoke()」とすることで、渡ってきた関数を実行させることができます。
渡ってくる関数に引数がある場合も対応できます。
void ProcessWithLogging(string fileName, Action<string> action)
{
Console.WriteLine($"[{fileName}] 処理開始");
action.Invoke(fileName);
Console.WriteLine($"[{fileName}] 処理終了");
}
なぜInvokeを使うのか
ここからは、なぜInvokeを使うのか、Invokeを使うことによるメリットを紹介したいと思います。
- 共通処理の外枠(トランザクション、ロギング、ロック処理など)を1か所にまとめられる
- 中身の処理を柔軟に差し替え可能 → 拡張性・保守性が高くなる
- 呼び出し側が「何をしたいか」に集中でき、共通部分は抽象化できる
呼び出し側が実際の中身の実装だけに集中することができ、それ以外の共通処理のことは気にしなくて良いのが最大のメリットであると思います。
処理の型だけを決めて具体的な実装部分は抽象化して呼び出し側に委譲するすることができます。
関数呼び出しとの違い
当初持っていた関数の呼び出しとあまり変わらないのでは疑問に対しての自分なりの違いは以下のようになります。
観点 | 関数化だけ | 関数を引数で渡す(+ Invoke) |
---|---|---|
再利用性 | 低め | 高い(共通枠を汎用化できる) |
柔軟性 | 固定処理向き | 可変処理に対応 |
呼び出し側が定義できる範囲 | 固定 | 柔軟に定義可能 |
実装の自由度 | 限定的 | 関数型的な構造も可能 |
変わる部分だけを引数で渡して、共通処理を抽象化するという考え方が Action.Invoke()と関数との大きな違いかと思います。
抽象化する共通処理がケースによって異なる場合、例えばテスト用のモック処理なども行うことができます。
まとめ
いかがだったでしょうか。
Invokeメソッドの基本は理解できたのではないかと思います。
曖昧な理解のままだと、再度目にした時にまた理解から入る必要があったり自分がコードを書く際の選択肢に出てこなかったりするのできちんと整理ができてよかったです。
「なぜこんなメソッドがあるのか」、「他の似たようなものとの違いは何なのか」といった疑問を持ちながらだと具体的なユースケースなどがイメージしやすくて深い理解に繋がりやすいと思います。
ぜひ参考にしてみてください。