web-dev-qa-db-ja.com

varキーワードのポイントは何ですか?

var キーワードは、明示的な型宣言の必要性を排除し、私は興味を持って SOディスカッション が適切である可能性がある場合を読みました。

Boo についても読んだことがあります。これは、 ローカル変数を宣言するオプション にすることでさらに一歩進んだようです。 Booを使用すると、型と宣言の両方を暗示することができます。

なぜC#言語の設計者はvarキーワードをまったく含めなかったのでしょうか?

Update:はい、varは匿名型をサポートしていますが、匿名型自体はvarキーワードを必要としません。

var anon = new { Name = "Terry", Age = 34 };

versus

anon = new { Name = "Terry", Age = 34 };
47
Ed Guiness

更新:ここには2つの関連する質問があります。実際には次のとおりです。1。変数を宣言する必要があるのはなぜですか。 2.変数を宣言する言語での「var」の用途は何ですか?

(1)の答えはたくさんあり、この質問の他の場所で見つけることができます。 (2)に対する私の答えは以下のとおりです。

他のコメント投稿者が言っているように、LINQは匿名タイプにこれを使用します。ただし、LINQは実際には、式の右辺の型がプログラマーに不明であるか、非常に冗長である、より一般的な問題のインスタンスです。考えてみましょう:

SomeGeneric<VeryLongTypename<NestedTypename>> thing = new   
SomeGeneric<VeryLongTypename<NestedTypename>>();

冗長でエラーが発生しやすいですよね?だから今、彼らはあなたにこれをさせます:

var thing = new SomeGeneric<VeryLongTypename<NestedTypename>>();

情報の重複を減らすことにより、エラーが排除されます。ここでは、入力エラーだけではないことに注意してください。コンパイラが左から右にサイレントにキャストできるように、左側の式のタイプが誤って入力される可能性がありますが、キャストは実際には右辺値。右辺値によって返される型が不明または匿名である可能性がある場合、これはさらに重要です。

45
JSBձոգչ

Varキーワードがないと、既存の変数を実際に使用するつもりだったときに、誤って新しい変数を作成する可能性があります。例えば.

name = "fred";
   ...
Name = "barney"; // whoops! we meant to reuse name
47
Ferruccio

私はvarの必要性を理解しており、それは大きな目的を果たします。キーワードがなく、型なしでその場で変数を定義するだけでは怖いです。あなたが1年以上触れていないコードを作り直す必要がある場合、あなたのコードを維持しなければならない次の人またはあなた自身を傷つけます。それがC#で開く必要があるドアかどうかはわかりませんが、varが必要のないときに使いすぎたときに、すでに読みやすさの問題を引き起こしているので、そうではないことを願っています。

私が最近見ているほとんどすべての.net3.5の例では、すべての変数がvarで定義されています。

私が主張するのは、使いすぎたときにキーストロークを節約するために、読みやすさを本当に犠牲にしているということです。例えば:

// What myVar is, is obvious
SomeObject myVar = new SomeObject();

// What myVar is, is obvious here as well
var myVar = new SomeObject();

私が見る問題は、人々がそれをどこでも使用しているということです...例えば:

// WTF is var without really knowing what GetData() returns?
// Now the var shortcut is making me look somewhere else when this should
// just be readable!
var myVar = GetData();

// If the developer would have just done it explicitly it would actually
// be easily readable.
SomeObject myVar = GetData();

したがって、次の議論は、関数に名前を付けるだけです...

var weight = GetExactWeightOfTheBrownYakInKilograms();

何が戻ってくるのかまだわかりません。それはint、decimal、float、weightオブジェクトですか?私はまだそれを調べるのに時間を無駄にしなければなりません...私の怠惰なプログラミングから一日を救うためにインテリセンス松葉杖が必要です。関数名に戻り値の型を含めるかもしれません。 varを使用しても、すべての関数に実際の長い名前を付ける以外に何も節約できません。

人々はvarを使いすぎていると思います。それは怠惰なプログラミングにつながり、ひいてはコードを読みにくくします。キーワードvarを入力するたびに、明示的ではなく、キーワードvarを使用する正当な理由があるはずです。

40
Kelsey

これは少し主観的ですが、キーワードがないのではなく、暗黙的に型指定された変数に対して「var」キーワードを持つようにC#3.0を設計すると、コードが読みやすくなると思います。たとえば、以下の最初のコードブロックは、2番目のコードブロックよりも読みやすくなっています。

変数が宣言されている場所は明らかです。

var myVariable = SomeCodeToSetVariableHere;
myVariable = SomeOtherCodeTOSetVariable;

変数が宣言されている場所が明確ではありません:

myVariable = SomeCodeToSetVariableHere;
myVariable = SomeOtherCodeTOSetVariable;

これらは単純すぎる例です。これがどこに行くのかわかると思います。複雑な状況では、変数が実際に定義されている場所を見つけることができれば便利かもしれません。

6
Jason Jackson

あなたの質問では、varは、コンパイラにWord anonが割り当てに含まれるタイプのアイテムが表示されると予想される場所での使用が合法であることを伝えることにより、コードに価値を追加します。このようにコンパイラーに名前の導入を要求すると、コンパイラーは、許可されていると明示的に指示されていないものを拒否できるため、コンパイル時に特定の種類のエラーをキャッチして、実行時に爆発しないようにします。

たとえば、質問の更新セクションで、次のスニペットについて質問しました。

anon = new { Name = "Terry", Age = 34 };

この方法で許可する場合の問題は、名前が以前は存在しなかった割り当ての左側にあるものが、実際にはタイプミスであっても、変数宣言に変換されることです。プログラムの後半でanonに何か他のものを割り当て、さらに新しい値を参照するときに、真ん中のステートメントにタイプミスがあった場合、実行時まで表示されない問題が発生します。

あなたの応答は、ブーがそれをするということです、それでそれは大丈夫か少なくとも可能でなければなりません。しかし、それは赤いニシンです。私たちはBooではなくC#について話している。 C#の目的の1つは、コンパイラーができるだけ多くのエラーをキャッチできる言語を用意することです。 Booもそれを望んでいますが、Pythonのようになりたいとも思っています。したがって、Pythonのような構文と引き換えに、C#のコンパイル時の安全性の一部(すべてではない)を犠牲にします。

4
Joel Coehoorn

免責事項:私の例はJavaです。それは私が知っていることだからですが、概念は同じである必要があります。

重要だと思う答えに投票しました(誤って新しい変数を作成するのは簡単すぎます)。

bill=5;
bi11=bill+5

請求書の価値はいくらですか?

そうは言っても、次のように入力するのは少しイライラすることがあります。

DataOutputStream ds=new DataOutputStream();

冗長に見えますが、正直なところ、実際には何も問題はありません。 2回入力するのにもう時間がかからず、非常に役立ちます。時間がかかるのは、質問があるとき、つまりAPIの使い方がよくわからないときです。その型宣言を2回入力するのが本当に面倒な場合は、なぜここで時間を無駄にしているのでしょうか。これを読み始めてから、30または40の宣言を入力できたはずです。これは、次の2週間に必要なすべての宣言に十分です。

私は自分自身を繰り返すことが引き起こす可能性のある感情的なストレスを理解していますが、一貫性、明快さ、そしてよりインテリジェントなツールを作る能力はそれを十分に価値があると言っていると思います。

もう1つ、ほとんどの場合、コードは上記の例のようにすべきではありません。あなたがすべきことはこれです:

DataOutput ds=new DataOutputStream();

これにより、具象クラスをテンプレートに使用しているという事実がすぐに隠されます。そのテンプレートは、クラスで必要なすべての操作を実行できる必要があります。後でdsを他の種類の出力ストリームに置き換えたい場合は、その1行を変更するだけで修正されます。 DataOutputStreamにキャストしてDataOutputで使用できない機能を使用していた場合、エディターはそれを簡単に理解して通知します。

2
Bill K