55

これは、プログラミングをするときにいつも疑問に思う質問です: コードを書くときに何を使うべきか:

var myFiles = Directory.GetFiles(fullPath);

また

string[] myFiles = Directory.GetFiles(fullPath);

varは新しく、 Implicitly Typed Local Variablesであるため、ローカルでしか使用できず、null にできないなどのルールがありますが、「普通に」使用する利点があるかどうかは疑問です。

「通常」の部分は、Anonymous TypesObject and Collection Initializers、およびQuery Expressionsではなく、 var 匿名オブジェクトを使用する意図があるため、上の例と同じように意味します。

あなたの考えは何ですか?

4

8 に答える 8

62

LINQ での明らかな使用以外に、var読みやすくするために毛むくじゃらの変数宣言を省略するためにも使用します。

var d = new Dictionary<string, Dictionary<string, Queue<SomeClass>>>();

一般的に、私は静的型付けから一種の快適さを得て (より良い言葉が欲しいのですが)、静的型付けをあきらめたくありません。変数を宣言しているときに自分が何をしているのかを知っているという感覚が好きです。変数を宣言することは、コンパイラに何かを伝えるだけでなく、コードを読んでいる人に何かを伝えることです。

例を挙げましょう。を返すメソッドがあるとしますList<string>。このコードは確かに正しく、C# 開発者の 90% がおそらくこのように書くと思います。

List<string> list = MyMethod();

もちろんですよね?実際、ここに同じように簡単に使用できる場所がありますvar

十分に真実です。しかし、このバージョンのコードは単に変数を宣言しているのではなく、それを書いた人が何をしようとしているのかを教えてくれます:

IEnumerable<string> list = MyMethod();

そのコードを書いた開発者は、「私はこのリストを変更するつもりはありませんし、そのメンバーにアクセスするためにインデックスを使用するつもりもありません。私がやろうとしているのは、それを繰り返し処理することだけです」と言っています。これは、1 行のコードで理解できる大量の情報です。使ったら諦めるものですvar

もちろん、最初から使っていなかったとしても、あきらめているわけではありません。あなたがそのようなコード行を書くような開発者であれば、varそこを使用しないことはすでにわかっています。

編集:

Jon Skeet の投稿を読み直したところ、Eric Lippert からの次の引用が目に飛び込んできました。

暗黙的に型付けされたローカル変数は、方法を強調せずに何を強調するかを示す小さな方法の 1 つにすぎません。

実際には多くの場合、暗黙的な型付けを使用すると、暗黙的なものを残していると思います。何にこだわらなくても大丈夫です。たとえば、次のような LINQ クエリをさりげなく記述します。

var rows = from DataRow r in parentRow.GetChildRows(myRelation)
           where r.Field<bool>("Flag")
           orderby r.Field<int>("SortKey")
           select r;

私がそのコードを読んだとき、私がそれを読んでいるときに思うことの 1 つは、「rowsIEnumerable<DataRow>. LINQ クエリが返すものは であることがわかっているためIEnumerable<T>、選択されているオブジェクトのタイプをすぐに確認できます。

それは、何が明示されていないかというケースです。それは私が推測するために残されています。

さて、私が LINQ を使用するケースの約 90% では、これはほんのわずかでも問題になりません。90% の確率で、コードの次の行は次のようになります。

foreach (DataRow r in rows)

rowsしかし、次のように宣言すると非常に便利なコードを想像するのは難しくありませんIEnumerable<DataRow>。多くの異なる種類のオブジェクトがクエリされているコードで、クエリ宣言を繰り返しの隣に置くことは現実的ではなく、次のようになります。rowsIntelliSense で検査できると便利です。そして、それはどのようにではなく、何をするかです。

于 2008-10-25T20:58:35.107 に答える
43

これについては、「どこでも var を使用する」から「基本的に必要な場合に匿名型でのみ var を使用する」まで、さまざまな意見が寄せられます。Eric Lippert の見解が気に入っています。

すべてのコードは抽象化です。コードが「本当に」行っていることは、データの操作ですか? いいえ、番号ですか?ビット?いいえ、電圧?いいえ、電子?はい、しかし電子のレベルでコードを理解するのは悪い考えです! コーディングの技術とは、聴衆にとって適切な抽象化のレベルが何であるかを理解することです。

高水準言語では、コードが (意味的に) 何をするのかと、コードがそれをどのように達成するのかということの間に、常にこの緊張関係があります。保守プログラマーは、変更を成功させるためには、何をどのように行うかの両方を理解する必要があります。

LINQ の要点は、「どのように」を大幅に強調せず、「何を」を大幅に強調するかということです。クエリ内包表記を使用することで、プログラマーは将来の聴衆に向けて、「この結果セットがどのように計算されているかを正確に知ったり気にしたりする必要はないと思いますが、結果セットのセマンティクスが何であるかについては非常に気にする必要があります」と言っています。それらは、実装されているビジネス プロセスにコードを近づけ、それを実行するビットや電子から遠ざけます。

暗黙的に型付けされたローカル変数は、方法を強調せずに何を強調するかを示す小さな方法の 1 つにすぎません。特定のケースでそれが正しいことであるかどうかは、判断の呼びかけです。したがって、型の知識が適切であり、その選択がメソッドの継続的な操作に不可欠である場合は、暗黙的な型付けを使用しないでください。明示的な入力は、「これがどのように機能するかを説明しています。注意してください」と言います。暗黙の型付けは、「これが List であるか Customer[] であるかはほとんど問題ではありません。重要なのは、それが顧客のコレクションであるということです」と述べています。

個人的には、型が合理的に明白でない場合は使用しない傾向があります。ここでは、LINQ クエリを「合理的に明白」であるとして含めます。Directory.GetFilesたとえば、それが (たとえば) a (またはまったく別のものstring[]) の代わりにa を返すことは明らかではないため、私はそれを行いません。これは後で行うことに大きな違いをもたらします。FileInfo[]

代入演算子の右側にコンストラクター呼び出しがある場合、私はvar. これは、複雑なジェネリック型で特に便利Dictionary<string,List<int>>です。

于 2008-10-25T19:25:47.727 に答える
12

個人的には、次の 2 つの場所でのみ var を使用します。

  1. 匿名型、つまり。LINQ 関連 (場合によっては var が必要)
  2. ステートメントが同じ型で特定の型を宣言および構築する場合

すなわち。これはポイント 2 の例です。

var names = new List<String>();

編集済み: これは、Jon Skeet の質問への回答です。

上記の答えは実際には単純化されています。基本的に、タイプが次のいずれかであるvarを使用します。

  1. 知る必要はありません(場所はそれほど多くありませんが)
  2. 知ることは不可能 (LINQ、匿名型)
  3. 別の方法で知られている、またはコードから明らかな

ファクトリ メソッドの場合、コードを記述する場所で知る必要があるのは、返されるオブジェクトが何らかの型の子孫であり、そのに静的ファクトリ メソッドがあることだけです。変数。このような:

var connection = DatabaseConnection.CreateFromConnectionString("...");

上記の例は、私のコードの実際の例です。少なくとも私とこのコードを使用する人々にとって、接続が DatabaseConnection の子孫であることは明らかですが、コードを理解したり使用したりするために正確なタイプは必要ありません。

于 2008-10-25T19:30:53.723 に答える
9

私は「どこでも var を使用する」スタイルを試しました...そして、これが私がそれを使い続けなかった理由です。

  1. 時々可読性が低下する
  2. = の後で Intellisense を制限します
  3. 特にインテリセンスでは、「var」と入力するのは、「int」、「string」などと入力するよりもそれほど短くはありませんでした。

そうは言っても、私はまだLINQでそれを使用しています。

于 2008-10-25T19:41:45.213 に答える
4

型推論が日常を支配する関数型プログラミングの地から来た私はvar、可能な限りすべてのローカルに使用します。

Visual Studio では、ローカルの型が何か疑問に思っている場合は、マウスをその上に置くだけで済みます。

于 2008-10-26T04:21:12.873 に答える
3

この投稿には、いつ var 型インターフェイスまたはオブジェクト型を使用するかについての適切なガイドラインがあります。

于 2008-10-25T20:15:41.837 に答える
3

私はどこでも使用する傾向がありますvarが、同僚はやめて、読みにくいと言いました. そのため、現在はvar匿名型、LINQ クエリ、および右側のコンストラクターでのみ使用しています。

于 2008-12-13T16:41:04.790 に答える
1

これが Haskell で通常どのように処理されるかは興味深いと思います。Curry-Howard isomorphismのおかげで、Haskell の任意の式の (最も一般的な) 型を推論できるため、いくつかの例外を除いて、型宣言は本質的にどこでも必要ありません。たとえば、推論されるよりも具体的な型に意図的に制限したい場合があります。

もちろん、必要なものと推奨されるものは同じではありません。実際には、最上位の定義には常に型宣言があり、ローカライズされた定義には型宣言が省略されているという慣習があるようです。これは、ローカルの「ヘルパー」または「一時的な」定義の簡潔さと読みやすさとは対照的に、全体としての定義の読みやすさと明示性のバランスが取れているようです。私の理解が正しければ、そもそも "トップレベル" の定義 (メソッドやグローバル関数など) には使用できないため、これは C# の世界では "どこでもvar使用できる" という意味になると思います。varもちろん、「 」を入力するのは「int」と同じ数のキーストロークですvarが、ほとんどの例はそれよりも長くなります。

于 2008-10-25T21:46:39.893 に答える