C#
型推論

var(型推論)の利用指針について

var(型推論)とは

メソッド内のローカル変数を宣言する際に型宣言の代わりに使用することができます。
コンパイラが自動で型を判断してくれます。

var i = 10;
// int i = 10; と同じ

長い型名の代わりに var を使うとコードをスッキリします。

var dict = new Dictionary<string, int>();
//Dictionary<string, int> dict = new Dictionary<string, int>();

あくまで『暗黙の型指定』であって型がないわけではありません。
以下のコードはコンパイルが通らないので安心して使用できます。

var i = 10;
i = "10"; // <-コンパイルエラー。

var hensu; // <- コンパイルエラー。右辺から推論できない。

型を明示したコードと var を使ったコードは機能的には全く同じです。

var の使用が推奨される場面

変数の型が右辺から明らかである場合

以下のように型が明示的な場合には var を使用します。

var i = 10;

var msg = "Hello";

var hero = new Hero { ID = 10, Name = "magneto"};

var apple = new { Name = "王林", price = 100 };  // ※匿名型

for および foreach ループでのループ変数の型宣言

  • for ループの初期化
for (var x = 1; x < 10; x++) {...}
  • foreach のループ変数の初期化
foreach (var item in list) {...} 

var が非推奨なところ

右辺から型が明らかでない場合、var は推奨されません。
以下の例では result はユーザ定義の Result オブジェクトかもしれませんし、ただの文字列かもしれませんし型がよくわかりません。

var result = MyClass.GetInfo();

また複数の数値型を混在する場合にも var は避けられる傾向があるようです。

var nums = new[] { 1, 2, 3, 4, 5 };

nums の型は int[] になりますが、これに少数が混じれば double[] になります。
これにより不具合が発生するかもしれませんが、型を明示していれば防ぐことができます。

var の間違った使い方

型が分からないから変数名に型名を含める

変数名に含まれた型が正しいという保証はありません。
型が変わったのに放置されたままになった場合、読み手を混乱させます。

var intState = GetState(); 

dynamic の代わりに var を使用する

冒頭でも書きましたが、 var はあくまで暗黙の型指定であって型付けは明示的に宣言した場合と全く同じです。
dynamic は動的型付け変数を定義するものなのでそもそも用途が異なります。

IDEの補助

今までの説明と矛盾するかもしれませんが、以下のような場合、でも var はよく使われます。
通常、読み手は GetProductByID の戻り値は Prodcut 型と推測できます。

var product = GetProductByID(12);

Visual Studioならマウスを合わせるだけで型がポップアップされますし、 varにカーソルを合わせて定義にジャンプすればで型の詳細がわかります。
ただ、Git hub 等では型が明示されないので読みにくいかもしれません。
また、命名規則にいい加減な開発者が、 IList<Product> や読み手が予想しない型を返していた場合でも気づきにくくなります。

チームのレベル感

上記の通り、 var は『型が明示的』な場合に使われることが多いですが、型が明示的の基準が開発者によって異なるかもしれません。

例えばLINQです。

var list = new List<MyClass>() {...};
var query = list.GroupBy(item => item.Category); // 集約keyはint型とします。

慣れた開発者なら一目で query の型は IEnumerable<IGrouping<int, MyClass>> と理解できます。
LINQ に詳しくない開発者はコードの戻り値を理解するのは難しいかもしれません。
この他にも File.ReadLines()IEnumrable<string> を返すなど慣れた人には当たり前と思うことも他の開発者にはわからないかもしれません。

命名規則がしっかりしていて使用するライブラリがチームに浸透しているならこのような var の使用はアリだと思います。

参考

以上、C# の var についてまとめました。
Javaでも var が導入されるらしく、C#でも改めて使いどころ、利用指針を考えました。
(※ パッと見似ているようですがJavaの var が C# と同じかはわかりません。)