2012-08-16 6 views
8

可能性の重複:これに...これは "使用に近い宣言の移動"が本当に好ましいですか?

int Platypus; 
string duckBill1; 
string duckBill2; 
string duckBill3; 
. . . 
using (OracleDataReader odr = ocmd.ExecuteReader()) { 
    while (odr.Read()) { 
     Platypus = odr.GetInt32("Platypus"); 
     duckBill1 = odr.GetString("duckBill1"); 
     duckBill2 = odr.GetString("duckBill2"); 
     duckBill3 = odr.GetString("duckBill3"); 
     switch (Platypus) { 
     . . . 

を::
Is it better to declare a variable inside or outside a loop?

ReSharperのは、私はこれを変更したい

using (OracleDataReader odr = ocmd.ExecuteReader()) { 
    while (odr.Read()) { 
     int Platypus = odr.GetInt32("Platypus"); 
     string duckBill1 = odr.GetString("duckBill1"); 
     string duckBill2 = odr.GetString("duckBill2"); 
     string duckBill3 = odr.GetString("duckBill3"); 
     switch (Platypus) { 
     . . . 

...しかし、このように(少なくとも、そうであるように)、変数はwhileループを通して毎回1回N回宣言されています。 Resharperizedは元のものよりも本当に優れていますか?

答えて

16

はい、宣言された変数の範囲を制限しているので、これは良い方法です。ループ内で宣言すると、パフォーマンスに影響はありません。 Resharperがこの変更を提案している理由は、あなたがループ外でそれらを使用していないからです。

+5

ループ外に宣言した場合は、範囲が広くなり、解放に時間がかかることを意味します。 +1 –

+1

@AndreCalilスコープはコレクションの適格性とは関係がないので、そうはなりません。 rsbarro氏によると、パフォーマンスへの影響はゼロです。 –

+0

@JonHanna申し訳ありませんが、私はそのコレクションの中にコレクションがあるのか​​分かりません。メソッドのスコープで変数を宣言すると、メソッドの終了時まで変数は解放されません。スコープがちょうどループであれば(whileのように)、より早くリリースされます。また、空文字列でもメモリが割り当てられます:http://stackoverflow.com/a/6601485/1484750 –

2

コンパイラは一般に、変数自体がループ条件に依存しないため、そのような式を最適化し、ループ外で変数宣言を「リフト」します。これにより、最初の例で示したコードが効果的に生成されます。

この場合、Resharperの提案は、コンパイル済みのスコープを減らすだけでなく、いくつかの冗長なコード行を削除することです。

+0

宣言には、「この名前がこのスコープ内で使用されるときは...」という、コンパイルされたコードに変換されないことだけが浮かび上がることはありません。しかし、宣言が割り当てられていて、その割り当てがループの後半に上書きされていない場合(とにかく意味が変わる)、実際にはその可能性が最も高くなります。 –

4

はい、ただし、実行時に時間がかかりません。コンパイラがメモリの場所を再利用するだけで、メモリはそれ以上使用されません。

8

一般的に言えば、変数を可能な限り狭い範囲で宣言するのは良いプログラミング方法です。理由は:

  1. 情報非表示です。
  2. わかりやすい。
  3. 何かをボルクスリングする可能性は低いです。

ループの各繰り返しで変数が新しく宣言されたように見えますが、実行時ではなくコンパイル時に変数が宣言されているようです。変数は[s]のスタックフレームにスペースが割り当てられ、ループ上の各繰り返しで同じスペースが再利用されます。

関連する問題