web-dev-qa-db-ja.com

暗黙的に型指定されたローカル変数の使用

ReSharper の試用版をインストールしましたが、最初に気づいたことの1つは、明示的に型指定されたローカル変数を暗黙的に型指定された変数で常に置き換えることを常に提案していることです:

public string SomeMethod(int aParam)
{
    int aNumber = SomeOtherMethod(aParam);
    // should be changed to:
    var aNumber = SomeOtherMethod(aParam);
}

明示的に型指定された変数は読みやすい(より明示的)と思います。

ReSharperの提案についてどう思いますか?暗黙的に型指定された変数を使用する利点はありますか?暗黙的/明示的な変数はいつ使用しますか?

63
M4N

個人的には、宣言を読むだけで変数Typeを明確に区別できる場合にのみ「var」を使用します。

var someVariable = new List<int>();

上記の例では、「var」が「List <int>」を指していることは明らかです。

メソッド定義に移動して「var」が表す変数タイプを調べる必要がある場合や、Visual Studioのintelli-popupなどと呼ばれるものに依存する必要がある場合は、「var」を使用したくない私には大丈夫ではありません:

var someVaraible = SomeMethod();

つまり、返されるはずの「SomeMethod」関数は何ですか?コードの行を見るだけでわかりますか?いいえ、できません。そのため、これらの状況で「var」を使用することは避けています。

74
Rene

これについては多くの議論がありますが、ほとんどすべての場所で 'this'キーワードを使用するのと同じように、すべて個人的な好みに帰着すると思います。

Ipersonallyは明示的に型付けされた変数を好みますが、ネストされたジェネリックコレクションを使用する場合、暗黙的に型付けされた変数を使用すると読みやすくなります。見る:

Dictionary<string, Dictionary<string, string>> myDictionary = new Dictionary<string, Dictionary<string, string>>();

対:

var myDictionary = new Dictionary<string, Dictionary<string, string>>();

編集:this SOトピックは同じトピックをカバーしていますが、いくつかの素敵な返信があります: 使用するもの:varまたはオブジェクト名タイプ?

EDIT2:最近では非同期で多くの作業をしていますが、明示的に型指定された変数を使用すると厄介なバグを防ぐことができる場合があります。ユーザーのIDを返したいというこの愚かな例を考えてみましょう。 GetUserAsyncTask<User>を返すことも考慮してください。暗黙的に型指定された変数を使用する場合、次のようなものを使用することになります。

public long GetUserId()
{
  var user = GetUserAsync();
  return user.Id;
}

これはコンパイルされますが、間違っています。 「ユーザー」は実際にはTask<User>です。また、TaskにはIdプロパティも含まれているため、コンパイルされます。この場合、誤ってユーザーの代わりにタスクのIDを返します。

public long GetUserId()
{
  User user = GetUserAsync();
  return user.Id;
}

コンパイラは、タスクをユーザーにキャストできないと文句を言うので、上記はコンパイルされません。もちろん、awaitキーワードを追加することでこれを解決できます。

私は実際に一度これが私に起こったことがあります:-)

40
Razzie

まだ気付いていない人のために、Reshaperで「提案」を簡単に変更できます(Reshaper->オプション->言語->コンテキストアクション->「明示的な型指定を「var」に置き換える」)。

私は個人的にどこでも明示的な型指定を好むが、それについてあまりうるさくはない。

17
uli78

特にジェネリックが関係する可能性がある場合、巨大な型名よりもvar疑似キーワードを入力する方が簡単です。ただし、機能的に同一であることを知っておく必要があります。どちらの方法でもパフォーマンスの違いはありません。コンパイラーは、割り当ての右側の型を導出し、varをその型に置き換えます。 VBバリアントのように、実行時に発生していません。

6
Daniel Henry

FWIW、多くの場合、varキーワードはわかりやすいものです。特に...

  1. 割り当ての右側はコンストラクター式です。

    var map = new Dictionary>();

  2. ローカル変数には適切な名前があります。

HTH

6
Dustin Campbell