連載:[完全版]究極のC#プログラミングChapter4 Findメソッド川俣 晶2009/09/14 |
|
|
4.3 ForEachだけではない繰り返しメソッド
実は、System.Arrayクラスやジェネリックコレクションのクラスなどが持つ繰り返しメソッドはForEachメソッドだけではない。Find、FindIndex、FindAllのような検索系のメソッドも持っている。
「Findメソッド」はForEachメソッドとよく似ているが、繰り返しではなく検索に特化したメソッドである。
主な相違は2つある。
1つは、第2引数で指定するデリゲートがAction<T>ではなくPredicate<T>になっていることである。つまり、メソッドの戻り値がvoid型ではなくbool型になっている。メソッドがtrueを返すと繰り返しを打ち切るようになっている。もう1つは、引数のメソッドがtrueを返したときの列挙値を、Findメソッドそのものの戻り値として返すことである。
さて、ここで注目したいのは、trueを返すと繰り返しを打ち切るという効能である。これを使えば、break文がなくとも、それに相当するコードを書くことができる(リスト4.3参照)。
| |
リスト4.3 ForEachメソッドの代わりにFindメソッドを使った例 |
しかし、これは読んでうれしいコードではない。return文が2つもあり、返すtrue/falseも直感的に意味がわかりにくい。
さらにいえば、本来検索のためのFindメソッドを繰り返しのために使っていることも、コードのわかりにくさを生んでいるといえる。パッと見て、このソースが何をするものなのか、かなりわかりにくいといえるだろう。
では、やはりforeach文に回帰すべきなのだろうか?
そうではない。Findメソッドを前提に考えるなら、Findメソッドを検索という目的に特化してやれば、コードはすっきりと明快になる。つまり、検索とは関係ない結果の出力機能を第2引数の匿名メソッドの外に出すのである。これがリスト4.4である。
| |
リスト4.4 出力は検索と分ける |
これでコードはかなりすっきりした。特に、ラムダ式が単に1つの式を計算するだけでよくなったため、中カッコ抜きで直接式を書けるようになった点は大きい。
だが、実はこのソースにはもう1つ大きなメリットがある。検索機能と出力機能がソースコード上で完全に分離したのである。Array.Findメソッド呼び出し部分が検索機能であり、続くConsole.WriteLineメソッドが出力機能である。一方、foreach文を使ったリスト4.1では、この2つの機能は明瞭に分離されていない。
では、なぜ分離されていると良いのだろうか?
分離されていれば、バラバラに切り離して開発することが容易になるからである。特に、リスト4.4のコードは、Visual Studio 2008が持つリファクタリング支援機能の「メソッドの抽出」を使って、検索機能と出力機能を別々に切り出せることに注目しよう。
それに対して、foreach文を使ったリスト4.1は、出力機能だけを切り出すことはできるが、出力機能抜きの検索機能をメソッドに抽出することはできない。
実際に、リファクタリング支援機能で切り分けた例をリスト4.5に示す。
| |
リスト4.5 「メソッドの抽出」で検索機能と出力機能を分けた例 |
このソースには、明らかに冗長な変数がいくつも見られる。
そこで、リファクタリングカタログの1つである「ローカル変数の除去」を適用してみよう*6(リスト4.6参照)。
| |
リスト4.6 冗長なローカル変数を除去した例 |
このとおり、役割ごとのメソッドに分けられた非常にすっきりしたソースコードを得ることができた。後は、メソッドごとに分けてバラバラに改良することも容易だろう。
*6 念のために補足すると、リファクタリングは、ツールで実行するものではなく、人間が行うものである。ツールは、リファクタリングの書き換えの一部を自動化して支援するにすぎない。ローカル変数の除去は、Visual Studioが支援してくれるわけではないので、手動で書き換えて行う。 |
INDEX | ||
[完全版]究極のC#プログラミング | ||
Chapter4 Findメソッド | ||
1.4.1 MATステートメントの思い出 | ||
2.4.2 ForEachメソッドのbreak問題 | ||
3.4.3 ForEachだけではない繰り返しメソッド | ||
4.4.4 複数の結果がほしい場合 | ||
5.4.5 偉大なる前進とは何か? | ||
6.4.6 そして、LINQへ続く/【Exercise】練習問題 | ||
「[完全版]究極のC#プログラミング」 |
- 第2回 簡潔なコーディングのために (2017/7/26)
ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている - 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう - 第1回 明瞭なコーディングのために (2017/7/19)
C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える - Presentation Translator (2017/7/18)
Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
|
|