連載:[完全版]究極のC#プログラミングChapter1 C# 3.0らしいプログラミングとは?川俣 晶2009/07/31 |
|
|
1.2 C# 3.0らしいソースコードとは?
さて、そろそろ論よりソースである。能書きを重ねるよりも、実際のソースコードを見るほうがわかりやすいだろう。
同人ゲームのコードを書いているときに、「これは良い例だ」と思う事例に出合ったので、そのソースコードの断片をそのまま紹介しよう。
まずはじめに、試行錯誤で書き上げた後に、「これはC# 2.0らしくない……」と思ったコード、リスト1.1を紹介する。これはゲーム中で、主人公の位置を移動させる機能を持ったメソッドである。瞬間移動するWarpToメソッドと、時間をかけ歩いて移動するGoToメソッドの2種類がある。
| |
リスト1.1 C# 3.0らしくないソースコード(一部分) |
できるだけコメントを補っておいたので、特に内容の説明は行わない。C# 1.xプログラマーなら、問題なく読めるはずである。
さて、このソースコードにはどのような問題があり、どのような改善点がありうるだろうか? 純粋に構文レベルの問題として考えてみていただきたい。
では、実際にこのコードを書き換えた結果であるリスト1.2をお見せしよう。
リスト1.2では、C# 3.0の新機能である「ラムダ式」を活用している(ラムダ式については、第6章と第7章で詳しく解説する)。このリストを読むためにC# 1.xプログラマーが必要とする知識は、
- 「()=>{……}」という記述がデリゲート型の引数に代入できるラムダ式の書式であること
- ラムダ式は上位のスコープに属するため、上位スコープの変数を参照できること
の2点だけである。
| |
リスト1.2 C# 3.0らしいソースコード(一部分) |
このリスト1.1とリスト1.2を見ると、(ラムダ式を除けば)同じ名前の3つのメソッドから構成されているにもかかわらず、処理コードの所属するメソッドが大きく違うことがわかると思う。
リスト1.1では、移動時間計算とストリーキング成立チェックのコードは、共通処理を行うgoToメソッドに含まれていた。しかし、リスト1.2ではこの2つのコードは、GoToメソッドに書き込まれている。
この違いは、特にWarpToメソッドの動作を理解するためにソースコードを読んでいるプログラマーには大きな恩恵をもたらす。このようなプログラマーは、まずWarpToメソッドのソースを読み、そこから呼び出されるgoToメソッドのソースを追い掛けることになる。その際、リスト1.1ではWarpToメソッド経由では実行されない膨大なコードを見る羽目になる。しかし、リスト1.2ではそのようなコードをまったく見ることはない。
逆にいえば、GoToメソッドでのみ実行され、WarpToメソッド経由では実行されないコードはすべてGoToメソッドに含まれることになる。それにより、コードの把握しやすさ、メインテナンスのやりやすさが向上している。
それだけではない。
リスト1.2は拡張性も向上している。ここには、徒歩移動を行うGoToメソッドと特殊状況でやむをえず主人公の居場所を瞬間移動させるWarpToメソッドしかないが、そのほかに、電車移動を行うTrainToメソッドや自動車で移動を行うDriveToメソッドなどを追加する必要が生じたとしよう。それらのメソッドがGoToメソッドと違うのは主に移動時間の計算になるが、その計算処理は、引数でgoToメソッドに渡すというアーキテクチャである。そのため、次のようなコードを書き足すだけで、既存のメソッドは変更することなく、新しい移動手段を追加することができる。
| |
電車移動を行うTrainToメソッドを実装する場合の例 |
* 電車による移動時間計算の処理自体をgoToメソッドに渡すため、goToメソッド側は変更する必要がない。 |
一方、リスト1.1はすべてがgoToメソッド内に混在し、わかりにくく扱いにくい。
かといって、名前のあるメソッドを使ってラムダ式とほぼ等価のコードをC# 1.xでは書けないことに注意しよう。リスト1.2のGoToメソッドにおいて、変数hasOtherEyesは2つのラムダ式から参照されているが、これはラムダ式が上位のスコープに属するという機能面から可能になることである。
名前のあるメソッドにはそのような機能は存在しないので、どうしても値を渡したければ引数などを増やすしかない。しかし、引数を増やすとデリゲート型の定義も変わってしまうが、その場合、それを参照するすべてのコードに影響が及んでしまう。
すなわち、このような書き方は、C# 1.xではうまくできないのである。
つまり、この事例はソースコードのわかりやすさとカスタマイズのしやすさが向上している事例であり、かつ、C# 1.xではうまく書けなかったものがC# 3.0になって書けるようになった事例であるということができる。
INDEX | ||
[完全版]究極のC#プログラミング | ||
Chapter1 C# 3.0らしいプログラミングとは? | ||
1.はじめに/本書の位置づけ | ||
2.1.1 意外性あり? 本書で解説すること/C# 3.0の適用範囲/筆者の来歴 | ||
3.1.2 C# 3.0らしいソースコードとは? | ||
4.1.3 コードの遅延実行という例 | ||
5.1.4 インターフェースとの比較 | ||
6.1.5 後退するクラスの立場 | ||
7.1.6 クラスベースとプロトタイプベース | ||
8.1.7 クラスベースの問題点/【C#olumn】クラスの問題とは何か? | ||
9.1.8 JavaScriptとの相違点 | ||
10.まとめ/【C#olumn】金のハンマーと銀の弾丸―クラス至上主義 | ||
「[完全版]究極の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用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
|
|