58

先日、同僚とおしゃべりをしていて、彼らのコーディング標準varでは、C# でのキーワードの使用が明示的に禁止されていると聞きました。彼らはなぜそうなのかわからなかったので、私は常に暗黙の宣言がコーディング時に非常に役立つことを発見しました. 変数の型を見つけるのに問題があったことは一度もありません(VSで変数にカーソルを合わせるだけで、そのように型が得られます)。

C# で var キーワードを使用するのが悪い考えである理由を誰かが知っていますか?

4

17 に答える 17

73

2008 年 11 月に発行された.Net Framework Design Guidelines (すばらしい本)の作成者varは、Type が明白で明確な場合に使用することを検討することを推奨しています。

一方、varAnton Gogolev が指摘したように、使用するとコードを読むときにあいまいさが生じる場合は、使用しない方がよいでしょう。

本(付録A)では、実際に次の例を示しています。

var names = new List<string>(); // good usage of var

string source = GetSource();
var tokens = source.Split(' '); // ok; most developers know String.Split

var id = GetId(); // Probably not good; it's not clear what the type of id is

可読性が低レベルの開発者の気まぐれに左右されないようにするために、あなたの組織はあなたが価値がないと判断し、varそれを禁止した可能性があります。
残念ですが、便利なツールを自由に使えるのに、施錠されたガラスのキャビネットに保管しているようなものです。

ほとんどの場合、varfor simple 型を使用すると、実際には読みやすくなります。また、 を使用してもパフォーマンスが低下しないことを忘れてはなりませんvar

于 2009-02-13T11:41:53.637 に答える
34
var q = GetQValue();

は確かに悪いことです。でも、

var persistenceManager = ServiceLocator.Resolve<IPersistenceManager>();

私にはまったく問題ありません。

肝心なのは、わかりやすい識別子名を使用すれば、うまくやっていくことができるということです。

補足として、キーワードの使用が許可されていない場合、匿名型をどのように処理するのだろうかvar。それとも全く使わないのですか?

于 2009-02-13T11:29:14.883 に答える
18

確かにこれは間違いです。これは、それが実際には厳密に型指定されており、VB の var とはまったく似ていないことに気付いていない人がいるからです。

すべての企業コーディング標準が意味をなすわけではありません。私はかつて、すべてのクラス名に会社名のプレフィックスを付けたいと考えていた会社で働いていました。会社が社名を変更したとき、大規模な手直しがありました。

于 2009-02-13T11:28:57.520 に答える
10

まず、原則として、コーディング標準はチームで議論して合意し、その背後にある理由を書き留めて、誰もがその理由を理解できるようにする必要があります。ワンマスターからの聖なる真実であってはなりません。

第 2 に、コードは書き込まれるよりも読み取られる回数の方が多いため、この規則はおそらく正当化されます。var書き込み速度は速くなりますが、読み取り速度が少し遅くなる可能性があります。var2 つの選択肢 (書き込みと型の書き込み) はまったく同じ動作をするため、「常に変数を初期化する」のようなコード動作規則ではないことは明らかです。したがって、これは重要なルールではありません。私は禁止しませんvar、私はただ「優先...」を使用します

于 2009-02-13T11:55:59.310 に答える
8

数か月前に、このトピックに関するブログ記事を書きました。私にとっては、可能な限りあらゆる場所でそれを使用し、特に型推論を中心に API を設計しています。型推論を使用する基本的な理由は次のとおりです。

  1. 型安全性を低下させない
  2. 暗黙のキャストを警告することで、コードの型安全性を実際に高めます。foreach ステートメントの最良の例
  3. C# で DRY 原則を維持します。これは宣言の場合に特化したものですが、わざわざ名前を 2 回言う必要はありません。
  4. 場合によっては、フラットアウトが必要です。匿名型の例
  5. 機能を失うことなくタイピングを減らします。

http://blogs.msdn.com/jaredpar/archive/2008/09/09/when-to-use-type-in​​ference.aspx

于 2009-02-13T13:48:27.543 に答える
6

varは、最新の「ブレースの配置方法」/ハンガリー語表記法/キャメル ケーシングの議論です。正解はありませんが、極端に座る人がいます。

あなたの友人は、彼らが過激派の 1 人の下で働いていることを残念に思っています。

于 2009-02-13T11:31:06.767 に答える
5

平易な英語で「var」を理解する

AND を使用して 'var' を使用しないことで、明確にコミュニケーションがとれることをお見せします。

「var」を使用するとコードが読みやすくなる例と、var を使用するとわかりにくい場合の例を示します。

それ以上に、「var」がどれほど明確かは、コード内の他のすべての名前に大きく依存することがわかります。

次の例を見てください。

ジェイクはビルに挨拶した。彼は彼が気に入らなかったので、向きを変えて別の道に行きました。

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

ジェイクはビルに挨拶した。ジェイクはビルが気に入らなかったので、向きを変えて反対方向に行った。

この場合、より具体的にすると文がより明確になります。しかし、常にそうであるとは限りません。場合によっては、具体的にすると読みにくくなります。

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

この場合、「彼」を使用し、場合によっては彼の名前をすべて省略した方が文が読みやすくなります。これは、varキーワードを使用することと同じです。

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

これらのアナロジーは要点をカバーしていますが、ストーリー全体を語っているわけではありません。これらの例では、人を指す方法が 1 つしかないことを確認してください。Bill などの名前で、または「彼」や「彼」などのより一般的な方法で。しかし、私たちはたった 1 つの単語で作業しています。

コードの場合、型と変数名の 2 つの「単語」があります。

Person p = GetPerson();

p問題は、何が何であるかを簡単に判断するのに十分な情報があるかということです。このシナリオでどのような人がいるか、まだわかりますか?

var p = GetPerson();

これはどう:

var p = Get();

これはどう:

var person = Get();

またはこれ:

var t = GetPerson();

またはこれ:

var u = Person.Get();

特定のシナリオでキーワードvarが機能するかどうかは、コードの複雑さだけでなく、変数、クラス、メソッドの名前など、コードのコンテキストに大きく依存します。

var個人的には、より包括的なキーワードを使用するのが好きです。しかし、私はまた、型にちなんで変数に名前を付ける傾向があるので、実際に情報を失うことはありません.

とはいえ、私は時々例外を設けます。これは複雑なものの性質であり、ソフトウェアは複雑ではありません。

于 2016-06-17T14:20:13.027 に答える
5

それを完全に禁止することは、匿名型の使用を禁止することを意味します (LINQ を使用するにつれて非常に便利になります)。

誰かが匿名型を決して使用しない正当な理由を形式化できない限り、これは単純明快な愚かさです。

于 2009-02-13T11:34:08.583 に答える
4

誤用すると可読性が損なわれる可能性があります。ただし、これを完全に禁止するのは少し奇妙です。同僚がそれなしで匿名型を使用するのに苦労するからです。

于 2009-02-13T11:29:07.957 に答える
4

C# は Microsoft の言語であるため、Microsoft の意見が適切であると考えることができます。

「ただし、varを使用すると、少なくとも他の開発者がコードを理解しにくくなる可能性があります。そのため、C# のドキュメントでは通常、必要な場合にのみvarを使用しています。」

MSDN - Implicitly Typed Local Variables (C# Programming Guide)の最後の段落を参照してください。


varは、最初の代入でコンパイル時のデータ型テストを削除することにも注意してください。

var x = "mistake";     // error not found by compiler
int x = "mistake";     // error found

ほとんどの変数は 1 回だけ割り当てられるため、一貫してvarを使用すると、変数の割り当てに関するほとんどすべてのデータ型テストが削除されます。

これにより、コードは偶発的な変更 (マージ ツールや疲れた開発者による変更など) に対して脆弱になります。

于 2014-09-09T08:59:24.953 に答える
3

Declaration Department of Declaration Department (Jeff's Coding Horrorから):

「コードをより簡潔にするために、いつでもどこでも暗黙の変数型付けを使用しています。言語の切り替えを含め、コードから冗長性を取り除くことはすべて積極的に追求する必要があります。」

私自身は検討する価値があると思います、いつ使用するか、または使用しないかについて包括的なガイドラインを作成するのはやり過ぎです。

于 2009-02-13T13:01:31.620 に答える
2

エリック・リッパートはそれをうまくまとめています

  • 必要な場合は var を使用してください。匿名型を使用している場合。
  • 宣言の型がイニシャライザから明らかな場合、特にオブジェクトの作成の場合は、var を使用します。これにより、冗長性が排除されます。
  • コードが変数のセマンティックな「ビジネス目的」を強調し、そのストレージの「機械的」詳細を軽視する場合は、var の使用を検討してください。
  • コードを正しく理解して維持するために必要な場合は、明示的な型を使用します。
  • 「var」を使用するかどうかに関係なく、わかりやすい変数名を使用してください。変数名は、ストレージの詳細ではなく、変数のセマンティクスを表す必要があります。「decimalRate」は悪いです。「利率」いいですね。

私自身の意見: intstringboolさらにはUser. 結局のところ、それは読みやすさに関するものです (LINQ で使用する場合を除く)。そのため、変数が散らばっていると、読みにくくなり、言語設計者が意図したキーワードの目的が損なわれる可能性があります。

于 2013-01-22T21:48:01.517 に答える
2

暗黙の型付けは素晴らしいものであり、それを全面的に禁止する人は生産性を損ない、脆弱なコードを招きます。

これは、リファクタリングの際に非常に便利な、タイプ セーフでコンパイラ チェック済みのダック タイピングに似ています。たとえば、List を返すメソッドがあり、それをリファクタリングして IEnumerable を返す場合、var キーワードを使用し、IEnumerable メソッドのみを使用するそのメソッドの呼び出し元は問題ありません。List などを明示的に指定した場合は、どこでも IEnumerable に変更する必要があります。

明らかに、暗黙型指定の呼び出し元のいずれかが List メソッドを必要とする場合、ビルド時にコンパイル エラーが発生しますが、その場合は、とにかく戻り値の型を変更するべきではなかったでしょう。

于 2009-02-13T12:57:16.917 に答える
1

var を使用すると、実際の DataRow 型ではなく、何らかの基本クラスの型になる場合がありました (Table.Rows コレクションを介して foreach する場合)。varで問題が発生したのはこれだけです。

于 2009-02-13T12:56:10.307 に答える
-5

var明示的な型付けとの効率性について私が実行したテストの結果は次のとおりです。

  private void btnVar_Click(object sender, EventArgs e)
    {
        Stopwatch obj = new Stopwatch();
        obj.Start();
        var test = "Test";
        test.GetType();
        obj.Stop();
        lblResults.Text = obj.Elapsed.ToString();
    }

    private void btnString_Click(object sender, EventArgs e)
    {
        Stopwatch obj = new Stopwatch();
        obj.Start();
        string test = "Test";
        obj.Stop();
        lblResults.Text = obj.Elapsed.ToString();

    }

最初のラベルの結果: 00:00:00 000034

2 番目のラベルの結果: 00:00:00 00008

于 2012-08-01T22:58:38.470 に答える