http://blogs.wankuma.com/rti/archive/2007/12/26/114624.aspx
暗黙的型付け(その2)
http://blogs.wankuma.com/rti/archive/2007/12/25/114456.aspx
暗黙的型付け
上記のタイトルのコメントですが、更に濃い反応をいただいたため、再び1タイトルとして独立させることにしました。
前回の論点は、var は型を明らかにしていない訳ではなく、きちんと型を意識していることを力説した内容でした。
その後の問題としては、この読み換えが容易かどうかという部分だけになってきているように思います。
それにしても、アンチ var 派の人って多いんですね・・・^^;
ちなみに、コメントを読んでいて思ったのですが、僕のサンプルコードは、既存のソースコードを眺めた場合という前提がついています。
今回は、後になって読んだ時に、そのコードが var によって本当に難読化されてしまっているのかに論点を絞ってみたいと思います。
まずは、お馴染みのコードを少々改良してみました。
public void HogeHoge() {
double a1 = this.GetAmount();
this.SetAmount(a1);
int a2 = this.GetAmount();
this.SetAmount(a2);
var a3 = this.GetAmount();
this.SetAmount(a3);
this.SetAmount(this.GetAmount());
}
private string amount;
private int GetAmount() { return 1; }
private void SetAmount(object value) { this.amount = value.ToString(); }
実行してみるまでもなく、問題無く動くことがわかるかと思います。
このコードを見た上で、もう一度、僕の言いたいことを繰り返しますと、a1, a2, a3 の型なんて、HogeHoge() メソッドの立場になって考えれば
どうでもいいこと
では無いでしょうか?
ここに int と明記する必要性は、僕には微塵も感じません。
あるいは、最初に double 型だったものが、後から GetAmount の戻り値を int に変更して、一部 double のまま修正し忘れてしまっているという場合もあるかもしれません(この時点で発見しにくいいバグですがなw)
これは、HogeHoge() メソッドにしてみれば、修正し忘れる行為自身「余計なこと」にはならないでしょうか?
HogeHoge() メソッドの役割は、GetAmount() から適切な値を受け取って、SetAmount() メソッドに渡すだけです。
以下のコードが GetAmount()から「何らかの値」という中間結果を受け取って SetAmount() に渡していると考えた場合、何らかの値の型を皆さんは意識しているのかどうか、と同義ではないでしょうか。
this.SetAmount(this.GetAmount());
さて、では次のコードを見て下さい。
private int unitPrice;
private int quantity;
:
private int GetAmount1() {
return unitPrice * quantity;
}
private int GetAmount2() {
var u = unitPrice;
var q = quantity;
return u * q;
}
GetAmount1 のような記述は許せて、GetAmount2 のような記述はすべきではないという明確な理由が僕にはわかりません。
次に、以下のコードです。
HogeHogeDataSet.ClientMaster a = new HogeHogeDataSet.ClientMaster();
System.Data.DataTable b = new HogeHogeDataSet.ClientMaster();
IDisposable c = new HogeHogeDataSet.ClientMaster();
2~3行目の場合は型を明示しますが、1行目は迷わず var を使います。
HogeHogeDataSet.ClientMaster a = new HogeHogeDataSet.ClientMaster();
var a = new HogeHogeDataSet.ClientMaster();
これは、以下のように書く理由と全く同じです。
var i = 5;
var d = 2m;
for (var i = 0; i < count; ++i)
= の右辺で型を明確に表しているのですから、わざわざ以下のように記述する必要を感じません。
int i = 5;
decimal d = 2m;
for (int i = 0; i < count; ++i)
確かに上記が気持ち悪く感じた時期が僕にもありました。
しかし、そもそも for で使う i のような使い捨ての変数は、int とでもしておけばいいだろうという程度で型を選択しているのですから、そこに var と書くことに何の抵抗もある筈が無いのです。
#なんてことを書いてみるテスト・・・^^;