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
にカーソルを合わせて定義にジャンプすればで型の詳細がわかります。
ただ、GitHub 等では型が明示されないので読みにくいかもしれません。
また、命名規則にいい加減な開発者が、 単数を返す関数名なのにコレクション型List<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# のコーディング規則 - MicroSoft
- 暗黙的に型指定されるローカル変数 (C# プログラミング ガイド)
- [雑記] 型推論の是非
- var の使いどころ
- 【JDK 10】varを使った型推論
以上、C# の var
についてまとめました。
Javaでも var
が導入されるらしく、C#でも改めて使いどころ、利用指針を考えました。
(※ パッと見似ているようですがJavaの var
が C# と同じかはわかりません。)