InfoQのC#討論:いつvarを使用すべきか?を読んだ。
僕は使う派だけど。。。ってReSharper大好きなんだから、当然ですが。。
コンパイラですら型が類推できるんだから、コードをちゃんと読めば自分でも類推できる。あちこちいろんなことを書いてあるよりも、varで統一されてたほうが読み易く感じる今日この頃。
今時、変数の上にマウスカーソルを持っていけば、型なんて表示されるご時世。型なんて、ベースクラスしかきてないこともざらで、そのときは、Polymorphismによっての、元の型を頭に思い浮べながら読むし。
varからvarへ暗黙キャストされると、さすがに、読みにくいけど、でもそれも、左辺がvarじゃなくても、暗黙キャストは読みづらいわけで。。。
てなことを考えると、ほとんどデメリットって無いんじゃないかしら。
varとVARIANT (dynamic)をちゃんぽんにしている議論は問題外。
結局のところ、コードが読み易いかどうかってのは、慣れの問題だし。
昔、CからC++に移行するときに、変数の宣言を、関数の始めに書くか、それとも使うところのそばで書くかって、話があって、まあ今となっては使うところのそばで書くひとが多いんだけど、当時は、使うところのそばだと、どんな変数がつかわれているのか、一覧性がなくて見づらい、なんて意見もあったわけで。
極端な例では、あまりにも長い関数を、読みづらいからって、複数の関数に分離して、ついでにファイルも分けたら、ひとつの関数じゃないと、あちこち飛ばないといけないから、読みづらいって言われたこともあるし。(なんじゃそりゃ、ですが)
ぶっちゃけて言ってしまえば、僕にとっては、TABが4じゃないとか、括弧が改行されずに行のうしろにあったりしたほうが、よっぽど読みづらいわけで。。
それよりも、読みづらいのが、ルールが統一されていないこと。
僕は、TABが4じゃないと嫌いだけど、だからと言って、2TABのソースコードを編集するときに、4TABで編集してチェックインするほど、横暴じゃない。
一番長く、そのソースコードに接している(接しなければならない)人のお好みにあわせるタイプです。
でも、自分だけのコードのときは、全部var。その方が僕は読みやすいし。
LINQのような場合以外は使わない派ですけど、まぁどっちでもいいかな。
ジェネリックコレクションクラスでもかなり冗長な表記になるので、varでもいいかなと思う。
ただ、varに慣れると、
var b = a.Get();
なんてこと普通に書く奴が必ず出てくる。
Getの戻り値の型を変えると、コンパイルエラーになるがいいか、そうでない方がいいか…。
オイラは前者を好みます。
道具は使いよう、という結論で落ち着くのかな。
var b = a.Get();って普通に書く派(笑)。
まあaとかbとかの、とぼけた変数名は、さすがにやらないけど。。。
これって、本文にも書いたcastの問題に通じるところがあって、極端な例だけど、
float b = a.Get();
で、Get()の返値の型をfloatからdoubleに変更した場合、warningが出る。varの場合だと出ない。
でもvarで受けている以上、bを使っているところがあるはずで、その使っているところでwarningがでるはず。
warningが出ないケースは、その使っている場所で暗黙キャストがかかっている場合。
double b = a.Get();
で、Get()の返値の型をdoubleからfloatに変更しても、何もおこらない。やっぱり、この件でも、何もおこらないのは、ここで暗黙キャストがかかっているから。
float/doubleの例をクラスのベース/派生に変えても、同じことになるのではないかと。
ぜんぜん違う型に変更した場合は、使っている場所でエラーになる。この場合は確かに、変更点でerror / warningにならずに、離れたところででるというデメリットになるね。(それでもvarはローカル縛りだから、範囲は限定されるかな)
あ、完全に同形のメソッドが存在してて、それを使ってた場合は、気がつかないケースもあるのか。
そんな例外を考えたら、いくらでも出てきそうだけど。
まあ、普通、返値の型を変更するときは、依存関係をチェックする気がするという方向で。。。(自分じゃない人が提供するライブラリだと、面倒か。。)
他にもint->float->doubleという、計算精度(?)を変更するようなことは、よくあるけど、この場合、varで受けてると、あちこち、いじらなくてもよくて、楽な場合もある。これを、楽と見るか、危険と見るかでも違うね。(varをC++のテンプレート的に使ってる?)
まあ このへんまで考えると、varだからどう っていうことよりも、それ以外の要因の方が重くなってくるのかな。
受け側で、変数名が型を類推させるような名前(今更のハンガリアンじゃなくて、クラスでもそんな名前あるじゃん)になっていた場合、ある関数の返値の型が変更された場合に、読みやすさを考えて、受け側の変数名まで、変更するか、面倒だからしないかとかね。
結局、使いよう だな。
どこまでコンピュータに確認をさせて(コンパイル)、どこまで人間で確認(レビュー)するかの境目かと。
勉強になります。