先日、同僚とおしゃべりをしていて、彼らのコーディング標準var
では、C# でのキーワードの使用が明示的に禁止されていると聞きました。彼らはなぜそうなのかわからなかったので、私は常に暗黙の宣言がコーディング時に非常に役立つことを発見しました. 変数の型を見つけるのに問題があったことは一度もありません(VSで変数にカーソルを合わせるだけで、そのように型が得られます)。
C# で var キーワードを使用するのが悪い考えである理由を誰かが知っていますか?
先日、同僚とおしゃべりをしていて、彼らのコーディング標準var
では、C# でのキーワードの使用が明示的に禁止されていると聞きました。彼らはなぜそうなのかわからなかったので、私は常に暗黙の宣言がコーディング時に非常に役立つことを発見しました. 変数の型を見つけるのに問題があったことは一度もありません(VSで変数にカーソルを合わせるだけで、そのように型が得られます)。
C# で var キーワードを使用するのが悪い考えである理由を誰かが知っていますか?
2008 年 11 月に発行された.Net Framework Design Guidelines (すばらしい本)の作成者var
は、Type が明白で明確な場合に使用することを検討することを推奨しています。
一方、var
Anton 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
それを禁止した可能性があります。
残念ですが、便利なツールを自由に使えるのに、施錠されたガラスのキャビネットに保管しているようなものです。
ほとんどの場合、var
for simple 型を使用すると、実際には読みやすくなります。また、 を使用してもパフォーマンスが低下しないことを忘れてはなりませんvar
。
var q = GetQValue();
は確かに悪いことです。でも、
var persistenceManager = ServiceLocator.Resolve<IPersistenceManager>();
私にはまったく問題ありません。
肝心なのは、わかりやすい識別子名を使用すれば、うまくやっていくことができるということです。
補足として、キーワードの使用が許可されていない場合、匿名型をどのように処理するのだろうかvar
。それとも全く使わないのですか?
確かにこれは間違いです。これは、それが実際には厳密に型指定されており、VB の var とはまったく似ていないことに気付いていない人がいるからです。
すべての企業コーディング標準が意味をなすわけではありません。私はかつて、すべてのクラス名に会社名のプレフィックスを付けたいと考えていた会社で働いていました。会社が社名を変更したとき、大規模な手直しがありました。
まず、原則として、コーディング標準はチームで議論して合意し、その背後にある理由を書き留めて、誰もがその理由を理解できるようにする必要があります。ワンマスターからの聖なる真実であってはなりません。
第 2 に、コードは書き込まれるよりも読み取られる回数の方が多いため、この規則はおそらく正当化されます。var
書き込み速度は速くなりますが、読み取り速度が少し遅くなる可能性があります。var
2 つの選択肢 (書き込みと型の書き込み) はまったく同じ動作をするため、「常に変数を初期化する」のようなコード動作規則ではないことは明らかです。したがって、これは重要なルールではありません。私は禁止しませんvar
、私はただ「優先...」を使用します
数か月前に、このトピックに関するブログ記事を書きました。私にとっては、可能な限りあらゆる場所でそれを使用し、特に型推論を中心に API を設計しています。型推論を使用する基本的な理由は次のとおりです。
http://blogs.msdn.com/jaredpar/archive/2008/09/09/when-to-use-type-inference.aspx
var
は、最新の「ブレースの配置方法」/ハンガリー語表記法/キャメル ケーシングの議論です。正解はありませんが、極端に座る人がいます。
あなたの友人は、彼らが過激派の 1 人の下で働いていることを残念に思っています。
平易な英語で「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
個人的には、より包括的なキーワードを使用するのが好きです。しかし、私はまた、型にちなんで変数に名前を付ける傾向があるので、実際に情報を失うことはありません.
とはいえ、私は時々例外を設けます。これは複雑なものの性質であり、ソフトウェアは複雑ではありません。
それを完全に禁止することは、匿名型の使用を禁止することを意味します (LINQ を使用するにつれて非常に便利になります)。
誰かが匿名型を決して使用しない正当な理由を形式化できない限り、これは単純明快な愚かさです。
誤用すると可読性が損なわれる可能性があります。ただし、これを完全に禁止するのは少し奇妙です。同僚がそれなしで匿名型を使用するのに苦労するからです。
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を使用すると、変数の割り当てに関するほとんどすべてのデータ型テストが削除されます。
これにより、コードは偶発的な変更 (マージ ツールや疲れた開発者による変更など) に対して脆弱になります。
Declaration Department of Declaration Department (Jeff's Coding Horrorから):
「コードをより簡潔にするために、いつでもどこでも暗黙の変数型付けを使用しています。言語の切り替えを含め、コードから冗長性を取り除くことはすべて積極的に追求する必要があります。」
私自身は検討する価値があると思いますが、いつ使用するか、または使用しないかについて包括的なガイドラインを作成するのはやり過ぎです。
エリック・リッパートはそれをうまくまとめています:
私自身の意見: int
、string
、bool
さらにはUser
. 結局のところ、それは読みやすさに関するものです (LINQ で使用する場合を除く)。そのため、変数が散らばっていると、読みにくくなり、言語設計者が意図したキーワードの目的が損なわれる可能性があります。
暗黙の型付けは素晴らしいものであり、それを全面的に禁止する人は生産性を損ない、脆弱なコードを招きます。
これは、リファクタリングの際に非常に便利な、タイプ セーフでコンパイラ チェック済みのダック タイピングに似ています。たとえば、List を返すメソッドがあり、それをリファクタリングして IEnumerable を返す場合、var キーワードを使用し、IEnumerable メソッドのみを使用するそのメソッドの呼び出し元は問題ありません。List などを明示的に指定した場合は、どこでも IEnumerable に変更する必要があります。
明らかに、暗黙型指定の呼び出し元のいずれかが List メソッドを必要とする場合、ビルド時にコンパイル エラーが発生しますが、その場合は、とにかく戻り値の型を変更するべきではなかったでしょう。
var を使用すると、実際の DataRow 型ではなく、何らかの基本クラスの型になる場合がありました (Table.Rows コレクションを介して foreach する場合)。varで問題が発生したのはこれだけです。
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