なれる! .NETer! 春までにVBerを脱却して、モテカワコーディング!

やぁみんなこんばんわ! 今日も元気にVB書いてるかな? Wow! そいつぁゴキゲンだ!

ところでVBerのみんなは、自分たちの世間での評判、知ってるかな? うん、そうだね、くそみそだね!
実際、VBしか書けないよぉ〜〜って人で、まともなコード書いてる人は今まで(といっても僕の見てきた数は少ないけどね)一人もみたことないんだ。新人の子も、VB.NETで研修はじめてから、半年でびっくりするくらいのクソコードを量産するようになっていたしね。

そういった歯がゆい現実に対処するため、VBAからプログラミングを学びはじめて、今に至るまでひたすらVB.NETでコーディングしているというVBネイティブの僕が、ここ一年とちょっとで学んだあれやこれを載せたいとおもう。世の中に存在する、あるいはこれから生まれるVBコードが、少しでも良くなるように……ね!



目標

これだからVBerは……とあんま言われないようなコーディング。
つまり.NET的な、即C#に移行できるようなプログラミングスタイルを身につける!

まえおき

まず(そんな人はいないとおもいますが)、プライベートやなんかで自発的に勉強をしたい場合はVB.NETを選ぶのはやめて、他の言語を選びましょう。もっと良い言語がいくらでもあります。もしも.NETで開発をしたいというなら、C#を選びましょう。VBもいいとこあんだけどね、わざわざ;とか打たなくていいし。
この文章は、お仕事でVB.NETを強いられている初学者が一日のほとんどを費やす業務時間を、なるべく実り多くすごせたら良いなという意図でもって書かれた文章です。

あと、基本的にVB2010を対象にしています。2008以下を強いられている人がいた場合は、初級編か中級編以降でコンパイルの通らないコードが出てくるよーになるとおもうので気をつけましょう。
2010からは、一部を除いてC#と機能的に同等なのですが、2008以下はしょぼいので気をつけましょう。出来れば上司に掛け合ってバージョンをあげてもらうか、使う言語をC#にしてもらいましょう。

基礎へん

明日から実践できるよ!
きそへんについて

新人、ベテラン問わずなのですが、VBerを脱却出来ていない人のVB.NETコードには多くの共通点があります。彼らのコードはオールドタイプなプログラミングスタイル、それも良くない点を踏襲してしまっています。C言語やVB6ではないのですから、もう少し現代人らしいシャキっとしたコードを書きましょう。

基礎編では「知るだけで明日から実践できる」内容についておおくりする予定であります。

  • VB6の構文は使わない

何が嬉しいのか知りませんが、.NETでもまだVB6の文を使いたがる人が多く見られます。また、そういった人のコードを真似て新人が時代錯誤的なコードを書いてしまうケースもまま見られます。貧弱だったVB6と比べて、.NETの恩恵を享受できる現代のVBにとっては、どれも使うメリットよりもデメリットのほうが大きいものばかりです。

まとめ:
Redim, With, Do Loop, GoTo, On Error 〜〜などは使うのをやめましょう。

  • 制御構文の使い方に気を使う

数値をインクリメントするようなループ構造を書く場合、普通はForを使うかとおもいます。しかし何故かは知りませんが、VBerにはForよりもWhileやDo なんちゃら Loopを好む人を見かけます。

DIm i As Integer
i = 0
while i < 100
     ' なんかする
     i += 1
End while

上みたいなコードを書いている人がいたら今すぐやめましょう。何のためにFor文が存在するのか考えてください。For i As Integer =0 To 100と書きましょう。そして考えたら、ForではなくForEachを使うようにしてください。
あと、Doなんちゃらはクソの山なので使うのはやめましょう。

まとめ:
数値をインクリメントするような操作にwhileは使わないでForを使う。
Forではなく、foreachを使う。
Doなんちゃらを使うと頭がおかしくなって死ぬ。

  • メソッドの先頭で変数を全部宣言しない

なんでVBerってメソッドの先頭で変数を全て宣言したがるんですか? 古式ゆかしいC言語じゃないんですから、今すぐそんな真似はやめましょう。
あとなんでVBerってわざわざプリミティブ変数に初期化っぽい代入をしたがるんですか? どこで覚えた作法か知りませんが、わざわざIntegerを0代入しなくても、0で初期化されていますよ。非本質的な操作でソースコードを汚すのはやめましょう。
1000行以上あるメソッド、先頭で宣言された数十の変数、山脈めいてうねるForとIfのネスト。それが俺たちVBerの戦場だ……!

まとめ:
変数の宣言は使う時に。宣言と代入は一緒に行う。
Integerなんかのプリミティブ型の初期化は不要。


  • option strict / option infer はonにする

両者とも、Offにするメリットはないので、政治的な理由で制限されていない限りはOnにしましょう。option stric offが便利だと思うなら、もうPythonRubyみたいな動的言語やればいいじゃない! 中途半端にVBでゆるふわするのやめて!
あともうわざわざ頭文字を大文字にしていくのに疲れたので今後は適当でいきます。

  • (システム)ハンガリアンは使わない

変数の接頭に型名を付与する記法のことです。未だに使う人を非常に沢山見かけます。派生種としてメソッドに、返り値の型をつけるケースも見られます。bolChkHdk()みたいなメソッドですね。ちなみにHdkは日付の略です。クール!
重度のハンガリアン病患者はfncHogeMethod や clsHugaClass なんて名前を平気でつけてきます。こうなるともはやハンガリアンですらありませんね。ちなみにネタだと思われる方もいるかもしれませんが、マジです。
何故システムハンガリアンがいけないのかわからない方は、自分で調べてください。

また、変数の接頭に"意味を"表すプレフィックスをつけるアプリケーションハンガリアン(これが本来のハンガリアン記法です)というものがあり、こちらは変数名の付け方としては良いプラクティスであると言えます。
http://local.joelonsoftware.com/wiki/%E9%96%93%E9%81%95%E3%81%A3%E3%81%9F%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AF%E9%96%93%E9%81%95%E3%81%A3%E3%81%A6%E8%A6%8B%E3%81%88%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%E3%81%99%E3%82%8B/
上にリンクのあるJoelのブログでは、同じ文字列(string)のうち、エンコード済みのものとそうでないものを、変数にプレフィックスをつけることで区別しています。

変数の名前に気をつけましょう。そうすれば自然とシステムハンガリアンは使わなくなっていくはずです。ただし、WindowsFormを使う場合、コントロールの接頭に(例えばbtnSaveとかね)型名を付与するのはアリだと僕は思っています。


* 間違ったコードは間違って見えるようにする への反論 *1


  • 変数名は分かりやすいものを

どうしてかVBerには謎の省略記法をする人をよく見かけるが、真似をしてはいけません。今までみてきたVBerは全て、例外なくシステムハンガリアンとこの謎の省略記法を行っていますが、今すぐパンツを脱ごう。なんでも大昔は変数名に制限があったりとか、メモリがどうこうとかあったみたいですがそんな昔のことは忘れてください。
あと、VBerはなぜか「処理効率の良い書き方!」みたいなものが大好きですが、貴方達の知識の大半は勘違いや伝言ゲーム由来ですし、仮に真実だとしても大抵の分野で求められるものは処理効率>>>>>>>>可読性です。どうしても早くしてーとかメモリ食い過ぎだとかなんかそういうアレになったら、計測してボトルネックだけチューニングしましょう。

わざわざここであげつらうような真似はしませんが、特別な理由がないかぎりは変数名を無理矢理省略するのはやめましょう。ちなみに変数に限らず、クラス、メソッドも同様ですよ。

あと、ローマ字は使わないようにしましょう。辞書引きましょう。ローマ字を使うくらいならいっそのこと日本語で書いたほうが良いと思います。ただ、これもケースバイケースで、たとえば業務用アプリなんかの場合は英訳不能な業務用語が大量に出てきたりします。その場合はローマ字や日本語もありだと僕は思います。妥協も必要です。ただし、ローマ字を英語を中途半端に混ぜるのはやめましょう。ましてやスペルミスを放置するなんてのはほんともう、やめましょう。

とりあえずは上記のことを気にかけるだけでも、何も考えていないVBerコードが10倍は読みやすいコードになると思います。名前の付け方はとてもとても奥が深いです、のでコーディングする際は常に気を配りましょう。リーダブルコードとか、その手の本を買おう、英語を勉強しよう。


まとめ

とりあえず、以上で基礎編は終わりです。
テクニック的なことには一切触れていませんが、上記を実践出来ていなかった人は、これを守るだけでも10万パワー程度はコードの読みやすさは向上するかと思います。

いつ書くかはわかりませんが、次の初級編ではリーダブルな制御構文の書き方や、クラス、オブジェクト指向、そしてメソッドとデリゲートについてちょびっとだけ触れる予定です。
初級編を会得することで、コードの読みやすさは基礎編コードの100倍向上するかと思います。

中級編では、引き続きオブジェクト指向を学び、ジェネリクスLINQラムダ式、関数型的な知識について書く予定です。中級編をマスターすることで、コードの読みやすさは以前の10倍になると思います。

つまり、中級編を終えたら、貴方のプログラミング力はそこらへんのVB超人を軽く凌駕することになると思います。

上級編はやりません。もうそこまでやんならC#使いましょう。僕はまだ使ったことないですが、F#も良いというもっぱらの噂です(要出典)。つーか上級編とか僕がわかりませんすいませんすいません。

*1: 基礎編からは外れてしまうが——そもそもプリミティブ型をそのまま使うのではなく、適切に型を定義してそれを使うようにすべきだと僕は考えている。
例えば先の例のような場合は、エンコード済み、未エンコードを表すクラスを定義して文字列をラップしてやる。あるいはPOSTされた文字列そのものをラップする型を定義してやり、メソッドを通じてケースに応じた文字列を受け取る。とか? そんなかんじ
もちろん状況との兼ね合いもある。例えば瑣末なものにまでいちいち型を定義していると負担がおおきい(ここらへんのさじ加減はプロジェクトの状態や使う言語に依存するのかなーと思う)。
ただ、アプリケーションハンガリアンには脆弱性があり、それはつまるところ整合性のチェックが人間にゆだねられていることだ。型の定義をうまく使えば、例えば誤った形式、あるいは危険性のあるのパラメータを送った場合にコンパイラに警告させるようなことが可能となる。