web-dev-qa-db-ja.com

ReSharperがすべてに「var」を使用するのはなぜですか?

Visual StudioでReSharperを使い始めたばかりです(SOに関する多くの推奨事項の後)。それを試すために、最近のASP.NET MVCプロジェクトを開きました。私が提案していることに気づいた最初で最も頻繁なことの1つは、明示的な宣言のほとんど/すべてを代わりにvarに変更することです。例えば:

//From This:
MyObject foo = DB.MyObjects.SingleOrDefault(w => w.Id == 1);
//To This:
var foo = DB.MyObjects.SingleOrDefault(w => w.Id == 1);

intboolなどの単純なタイプでも同様です。

なぜこれが推奨されているのですか?私はコンピューターサイエンスや.NETのバックグラウンドから来たわけではありません。

203
Chris

1つの理由は、読みやすさの向上です。どちらが良いですか?

Dictionary<int, MyLongNamedObject> dictionary = new Dictionary<int, MyLongNamedObject>();

または

var dictionary = new Dictionary<int, MyLongNamedObject>();
181
Mark Sherretta

ReSharperが示唆しているのは、明らかにvarキーワードの過剰使用です。タイプが明らかな場合に使用できます。

var obj = new SomeObject();

タイプが明らかでない場合は、書き出す必要があります。

SomeObject obj = DB.SomeClass.GetObject(42);
281
Guffa

個人的には、この提案をオフにすることを好みます。 varを使用すると、多くの場合読みやすさが向上します。しかし、あなたが述べたように、それは時々それを減らします(単純な型の場合、または結果の型がobscureの場合)。

varを使用するときと使用しないときを選択することを好みます。しかし、再び、それは私だけです。

95
Bryan Menard

varは、コードの読みやすさを向上させ、コードの即時の理解度を低下させます。まったく同じように、他の状況でのコードの可読性が低下する可能性があります。時々それの使用は中立です。理解の読みやすさの尺度は比例ではなく、状況に依存します。両方が一緒に増減することもあります。

要因は、varが適用される対象と、ターゲットがリーダーへのデータ型の即時難読化をどれだけうまくサポートするか、または手元のプログラム部分を理解するためにその型情報が必要かどうかです。

たとえば、不適切な命名はvarにつながり、コードの理解度を低下させる可能性があります。ただし、これはvarの問題ではありません。

var value1 = GetNotObviousValue(); //What's the data type? 
//vs. 
var value2 = Math.Abs(-3); // Obviously a numeric data type. 

コードがない場合にコードが読みやすい場合、単純なデータ型にvarを使用しても意味がない場合があります。

var num = GetNumber(); // But what type of number?
// vs. 
double num = GetNumber(); // I see, it's a double type. 

varは、次の複雑さを必ずしも気にする必要のないデータ型情報を隠すのに役立ちます。

    IEnumerable<KeyValuePair<string,List<Dictionary<int,bool>>>> q = from t in d where t.Key == null select t; // OMG! 
    //vs. 
    var q = from t in d where t.Key == null select t;

    // I simply want the first string, so the last version seems fine.  
    q.First().Key; 

must匿名型が存在する場合は、varを使用します。呼び出し元の型名がないためです。

var o = new { Num=3, Name="" };

Visual Studio Intellisenseでvarにもかかわらず型情報を提供している場合は、支援なしで厳密なコード読み取りを行うことで、理解に頼る必要が少なくなります。誰もがIntellisenseを持っている、または使用しているとは限らないと想定するのがおそらく賢明です。

上記の例に基づいた要約varのc​​arte blancheアプリケーションは、ほとんどのことを適度に行い、手元の状況に基づいて行うのが最善であるため、お勧めできませんここに示す。

Resharperがデフォルトですべてを使用するのはなぜですか?状況のニュアンスを解析して、いつ使用しないのが最適かを判断できないため、簡単に提案します。

67
John K

ReSharper(8.02、しかしおそらく他のバージョン)では、「暗黙的に型指定されたローカル変数宣言を使用する」提案のオプションは、preferenceに調整できます。 ReSharper:

ReSharper Options Menu

次に、選択した言語の「検査の重大度」を調整することにより、「コード検査」の下で、私の場合はc#:

Turn off implicitly typed local variable suggestion

ご覧のとおり、ReSharperが行うすべての提案を調整するオプションがあります。これが、すでに「var」使用戦略を持っている私のような誰かを助け、ReSharperにそれを尊重することを望んでいます:)

38
Erikest

インスタンス化されたオブジェクトのタイプを変更する方が簡単だと誰も言及していないことに驚いています。

AVeryLongTypeName myVariable = new AVeryLongTypeName( arguments );

繰り返しの形式です。 AVeryLongTypeNameを派生クラスの1つに変更する場合、varを使用するときにこれを1回変更するだけで、子クラスのメソッドにアクセスできます。

それとは別に、読みやすさの向上は重要なポイントですが、他の人が言ったように、varを使いすぎてはいけないので、Resharperでヒントをオフにすることは絶対に大丈夫だと思います。

23
Philipp

「var」は明確であること

varキーワードを使用するかどうかに関する主な議論は、コードがあなたや他の開発者にとってどれだけ読みやすいかということです。

まるであなたが物語を書いているかのように、決定的な正しい答えはありません。しかし、わかりやすい英語でこの例をいくつか見てみましょう。

ジェイクはビルに挨拶しました。彼は彼が好きではなかったので、彼は向きを変え、反対の方向に進んだ。

誰が逆に行ったのですか?ジェイクかビル?この場合、「Jake」と「Bill」という名前を使用することは、タイプ名を使用するようなものです。そして、「彼」と「彼」はvarキーワードを使用するようなものです。この場合、より具体的にすることが役立つ場合があります。たとえば、次の例はより明確です。

ジェイクはビルに挨拶しました。ジェイクはビルが好きではなかったので、彼は振り返り、反対の方向に進みました。

この場合、より具体的にすることで文が明確になりました。しかし、常にそうなるとは限りません。特定のケースでは、読みにくくなります。

ビルは本が好きなので、ビルは図書館に行き、ビルはいつも好きだった本を取り出しました。

この場合、 "he"を使用すると文を読みやすくなり、場合によっては名前をすべて省略します。これはvarキーワードを使用するのと同等です。

ビルは本が好きなので、彼は図書館に行き、いつも好きな本を取り出しました。

これらの例は要点をカバーしていますが、すべてを語っていません。それらの例では、人を参照する方法は1つしかありませんでした。名前を使用するか、「he」や「him」などのより一般的な用語を使用します。

コードの場合、わかりやすくするための3つの方法があります。タイプ、変数名、および割り当て。たとえば、次のコード行をご覧ください。

Person p = GetPerson();

問題は、そのコード行に何が起こっているのかを把握するのに十分な情報があるということです。

次のコード行はどうですか?この場合、pの意味をまだ知っていますか:

var p = GetPerson();

今はどう:

var p = Get();

または今:

var person = Get();

またはこれ:

var t = GetPerson();

またはこれ:

var u = Person.Get();

キーワードvarが特定のシナリオで機能するかどうかは、変数、クラス、およびメソッドの名前の付け方など、コードのコンテキストに大きく依存します。また、コードの複雑さとそれを取り巻く残りのコードにも依存します。

個人的に私はvarキーワードを使用するのが好きです。それはより包括的です私にとってほとんどの場合。ただし、変数の名前は型にちなんで付けるので、実際には情報を失うことはありません。

それは時々、私が例外を作るコンテキストに応じて、それは複雑なものの性質であり、ソフトウェアは複雑ではないにしても何も言わない。

23
Luis Perez

これも嫌いだった。

私はこれをvarの使用に関する議論に変えたくはありません。それは用途はありますが、どこでも使用すべきではありません。

覚えておくべき重要なことは、ReSharperはあなたが望むコーディング標準に合わせて構成されているということです。

編集: ReSharper and var

17
LiamB

私のルールはこれです:

  • プリミティブ型を宣言していますか(つまり、bytecharstringint[]double?decimalなど)? ->タイプを使用:

    string myStr = "foo";
    int[] myIntArray = [123, 456, 789];
    double? myDouble = 123.3;
    
  • 複合型を宣言していますか(つまり、List<T>Dictionary<T, T>MyObj)? -> varを使用:

    var myList = List<string>();
    var myDictionary = Dictionary<string, string>();
    var myObjInstance = new MyObj();
    
13
Sumner Evans

多くの正解が表示されますが、完全な回答はありません。

Resharperがデフォルトでvarを使いすぎることは事実です。ほとんどの人がそれに同意すると思います。また、varが使用され、新しいステートメントを使用する場合など、タイプが明らかな場合も読みやすくなります。 varの使用に関するヒントのみを表示するように検査の重大度を更新する方法を示す1つの投稿を見ました。

これらを設定する場所を追加するために、最初に他の投稿にコメントしようとしましたが、評判がありませんでした。どうやら、設定のスクリーンショットを投稿する評判もなかったようです。

そこに着く方法を説明します。

Visual Studioの場合->メインメニュー-> Resharper->オプション->コード編集-> C#->コードスタイル->宣言での変数の使用

  • 組み込み型の場合明示的な型を使用
  • 単純なタイプの場合は、明らかな場合は「var」を使用します
  • 他の場所でUse'var '

enter image description here

12
Nathan Kovac

C#Coding Conventions "変数の型が割り当ての右側から明らかな場合、または正確な型ReSharperでデフォルトでヒントがオンになっているのは、おそらくそのためです。また、同じドキュメントのすぐ下で読みやすさが向上しない場合もあります。

12
jose

ReSharperはvarを推奨します。varを使用するとオブジェクトの作成が乱雑になる傾向があるためです。

これら2つの例を比較します。

StringBuilder bld = new StringBuilder();

var bld = new StringBuilder();

これは、読みやすくするための簡略表記です。

「new」で明示的に新しいオブジェクトを作成する場合は問題ないと思います。ただし、あなたの例では、クラスに適切な名前が付けられていないかどうかは明らかではないかもしれません。

6
Paul Sasik

ところで、ReSharperは「この提案をあなたのコードに適用したいかもしれない」と「あなたのコードが壊れているので、私にそれを修正して欲しい?」とを区別します。 varキーワードは、「ネストを削減する場合は反転」などの項目とともに提案カテゴリに含まれています。従う必要はありません。

[オプション]ダイアログから、またはそのアラートのポップアップメニューから直接、各アラートの煩わしさを設定できます。 var提案などをダウングレードして目立たないようにするか、「拡張メソッドを使用」アラートなどをアップグレードして実際のエラーとして表示することができます。

6
Tim Robinson

.Net 3.0のvar機能は単なる 型推論 であり、これは型安全であり、コードを読みやすくすることがよくあります。しかし、必要はありません。必要に応じて、リシャーパーでその推奨をオフにすることができます。

Varはすごい!私はvarが動的型にバインドされているという印象を受けている多くの開発者に出会いましたが、そうではありません。まだ静的に型付けされており、コンパイラーによって決定されただけです。

Varを使用することのいくつかの驚くべき利点があります

入力が少ないvarは短くて読みやすい

Dictionary<int,IList<string>> postcodes = new Dictionary<int,IList<string>>() Yuk。

var postcodes = new Dictionary<int,IList<string>>()\o/\ o /

よりわかりやすい変数名-貧弱なものですが、varの流動的な性質をここに反映させることが重要だと思います。 varは少し曖昧であるため、型にそれ自体を語らせるのではなく、実際にはより説得力のある変数名を推奨します。

コード変更が少ない-メソッド呼び出しの戻り値の型が変更された場合。メソッド呼び出しを変更するだけで、使用されているすべての場所を変更する必要はありません。

匿名型-匿名型は、特にWebApi 部分的なリソース などの分野で非常に強力な概念です。 varがなければ、使用できません。

ただし、明示的に型を宣言すると便利な場合もあります。これは、プリミティブまたは構造体で最も便利です。たとえば、私は個人的にこの構文は非常に便利だとは思いません。

for(var i = 0; i < 10; i++) 
{

}

for(int i = 0; i < 10; i++) 
{

}

それはすべて個人的な好みに依存しますが、varを使用すると、開発がスピードアップし、匿名型の良さの全世界のロックが解除されます。

3
KnowHoper

varキーワードはC#3.0で導入されました-タイプを明示的に指定することを忘れることができます。

使用するかどうかに実質的な違いはありません

MyObject foo = DB.MyObjects.SingleOrDefault(w => w.Id == 1);

または

var foo = DB.MyObjects.SingleOrDefault(w => w.Id == 1);

純粋な可読性とエラーの可能性の低下を除きます。

決まり文句の例のように思えますが、以下が理解に役立つかもしれないと言ってください:

var myInt = 23;

int型を返しますが、

var myInt = "23";

string型を返します。

MSDNリファレンス

2
Daniel May

明示的なオブジェクトタイプの指定は、なんらかの冗長性があります。英語に翻訳しても、冗長なように聞こえます。「タイプXのオブジェクトをタイプXの変数に入れる」対「タイプXのオブジェクトを変数に入れる」。

ただし、 'var'の使用には制限があります。以下のpolymorphismの使用を防ぎます。これはpure beautyです。

犬が動物を伸ばすと仮定します。 CatはAnimalクラス階層を拡張します:

Animal x = new Dog();
DoStuffWithDog(x as Dog);

x = new Cat();
DoStuffWithCat(x as Cat);

void DoStuffWithDog(Dog d){}
void DoStuffWithCat(Cat c){}

Xが 'var'で宣言されている同じコードコンパイルしない

var x = new Dog(); // from this point, x is a Dog
DoStuffWithDog(x as Dog);

x = new Cat(); // cannot assign a Cat instance to a Dog
DoStuffWithCat(x as Cat);

void DoStuffWithDog(Dog d){}
void DoStuffWithCat(Cat c){}

とにかく、元の質問に戻って、私はResharperを使用しませんが、それは 'var'を使用しない場合を検出するのに十分賢いと思います。 :-)

2
xtrem

私の見解では、varは、変数の値を定義するときに型が何であるかがすぐにわかる場合にのみ使用する必要があります。

例:

var s = "string value";

sstringであることは明らかです。

変数の型名が非常に複雑な場合にも適切だと思います。

例:

Dictionary<SomeCustomKeyType, Dictionary<AnotherCustomKeyType, List<int>>> dict = new Dictionary<SomeCustomKeyType, Dictionary<AnotherCustomKeyType, List<int>>>();

// This is a little easier to read than the above statement
var dict = new Dictionary<SomeCustomKeyType, Dictionary<AnotherCustomKeyType, List<int>>>();

これらのシナリオ以外では、varを使用してGAINが作成されることはありませんが、有害になる可能性のあるシナリオを考えることができます:

たとえば、右辺の変数値がタイプを明確に表示しない使い捨てタイプ。 IDisposableの廃棄は簡単に忘れられます。

例:

// returns some file writer
var wr = GetWriter();

wr.add("stuff");
wr.add("more stuff");

//...
//...

// Now `wr` needs to be disposed, 
// but there is no clear indication of the type of `wr`,
// so it will be easily overlooked by code writer and code reviewer.
2
James Wierzba

技術的な違いはありません。varを使用すると、コンパイラによって型が暗黙的に指定されます。このようなコードがある場合:

var x = 1;

xはintであると暗示され、他の値を割り当てることはできません。

Varキーワードは、変数のタイプを変更する場合に役立ちます。その後、2つではなく1つの変更を行うだけで済みます。

var x = 1; --> var x = "hello";
int x = 1; --> string x = "hello";
2
eWolf

「var」の継続的な使用を嫌う人のために:

注:「変数の導入」を行うときに、resharperがvarにデフォルト設定されるのを停止することもできます。これは長い間私を苛立たせたもので、常にvarにデフォルト設定されていたため、毎回変更していました。

これらの設定は、[コード編集]-> [C#]-> [コードスタイル]にあります。

enter image description here

1
Derek

'var'は、コードに一種の「動的」要素を追加します(ただし、コードはもちろん厳密に型指定されたままです)。タイプが明確でない場合は使用しないようにアドバイスします。この例を考えてみましょう:

var bar = GetTheObjectFromDatabase();
bar.DoSomething();

ClassA {
  void DoSomething() {
  //does something
  }
}

ClassB {
  void DoSomething() {
  //does something entirely different
  }
}

GetTheObjectFromDatabase()の戻り値のタイプがタイプAからBに変更された場合、両方のクラスがDoSomething()を実装するため、気付かないでしょう。ただし、コードは実際にはまったく異なることを行う場合があります。

これは両方ともログに異なる内容を書き込むのと同じくらい微妙かもしれないので、あなたはそれが手遅れであることに気付かないかもしれません。

次のvarの使用は常に問題ありません。

var abc = new Something();
1
lolaldanee

技術的な違いはありません(eWolfが指摘したように)。どちらを使用しても、生成されたCLRコードは同じように見えます。

私の意見では、主な利点は、これにより、より適切な変数命名を使用するように強制される傾向があることです。あなたの例では、「foo」は変数名としてはかなり貧弱な選択です。

0
Jaco Pretorius

JetBrains(ReSharperの作者)によると、デフォルトではvarの使用を推奨しています。

website から:

C#3.0で導入された暗黙的に型指定されたローカル変数(varキーワードとも呼ばれる)の使用は、結果のコードの可読性が向上したため、非常に一般的になりました。デフォルトでは、ReSharperはvarキーワードの使用も推奨していますが、その使用の設定は柔軟に構成可能です。たとえば、特定の場合またはどこでも明示的な型を使用することを選択できます。

0
Jeff Reddy