2009-06-04 7 views
12

は次のように私は整数の変数を初期化するかどうかのいずれかの違いがあります:C#の変数の初期化質問

int i = 0; 
int i; 

は、コンパイラやCLRは同じものとして扱うのか? IIRC、私は彼らはどちらも同じものとして扱われていると思うが、私は記事を見つけることができない。

+11

_Fields_は、フィールド型のデフォルト値に自動的に初期化されます。これは、int型の場合はゼロです。フィールドは明確に割り当てられているとみなされます。明示的な割り当ての前でも内容を読むことができます。 _Locals_は確実に割り当てられているとはみなされません。その内容が読み込まれる前にローカルの値を割り当てる何かをする必要があります。詳細については、C#仕様の「明確な割り当て」を参照してください。 –

答えて

6

私はIL(ildasmを使用)を見て、実際には0に設定されたintだけがコンストラクタで実際に0に設定されていることを確認しました。

public class Class1 
{ 
    int setToZero = 0; 
    int notSet; 
} 

は生成:

.method public hidebysig specialname rtspecialname 
     instance void .ctor() cil managed 
{ 
    // Code size  15 (0xf) 
    .maxstack 8 
    IL_0000: ldarg.0 
    IL_0001: ldc.i4.0 
    IL_0002: stfld  int32 ClassLibrary1.Class1::setToZero 
    IL_0007: ldarg.0 
    IL_0008: call  instance void [mscorlib]System.Object::.ctor() 
    IL_000d: nop 
    IL_000e: ret 
} // end of method Class1::.ctor 
+0

しかし、そのクラスのctorが明示的に割り当てられていない変数の変数の初期化を処理することはできませんか? –

+8

Michael:フィールドは、_constructor_ではなく、_memory manager_によってデフォルト(ゼロ)の値に初期化されます。 –

+0

説明のためにEric Lippertに感謝します。私は、このディスカッションに参加した一人以上の人に謝意を表したいと思います。 いつものように、私はいつも私がここに来たより多くの知識を忘れています;) – coson

4

はい、ほとんど同じことです。

あなたは、以下のリンク状態としてCoding Horror

+0

+1のリンク。このトピックに関する面白い議論。 – CAbbott

14

変数場合、私はそれは意志、インスタンス変数であります自動的に値0が割り当てられます。メソッド内のローカル変数の場合は未定義ですので、使用する前に値を割り当てる必要があります。例えば

class Program 
{ 
    static void Main(string[] args) 
    { 
     intTest it; 

     it = new intTest(); 

     Console.ReadLine(); 
    } 

    class intTest 
    { 
     int i; 

     public intTest() 
     { 
      int i2; 

      Console.WriteLine("i = " + i); 
      Console.WriteLine("i2 = " + i2); 
     } 
    } 
} 

i2が割り当てられていないため、コンパイルされません上記。しかし、実行している、その後、すなわち、I2に

int i2 = 0; 

を0を代入してコンパイルすることにより、両者は今0

+0

intはクラスではない構造体です。構造体はデフォルト値を持ちますが、クラスはデフォルトでnulです。 –

+0

@Matthew Whited、彼はそれがクラスであることを意味しませんでした。彼は実際にインスタンス変数を意味するクラス "レベル"で言っていました。私はそれを説明のために編集した。 – mmcdole

0

あなたがC#で型を作成するたびに割り当てられていることが示されます、それが自動的にで埋めますパディングされたゼロ。クラス(参照型)の場合、これはヌルポインタに相当します。だから、技術的に、あなたはクラスで作業している任意の時間、次は同じです:(int型/フロート/ダブル/などを含む任意の構造体、)値の型で

MyClass class; 
MyClass class2 = null; 

は、タイプにはゼロが渡されるので、以下は同等では:あなたがそれを使用する前に、あなたのタイプに値を割り当てた場合

int i; 
int j = 0; 

しかし、この方法では、コンパイラのかどうかを確認します。次の操作を実行した場合、コンパイラは文句を言うだろう:

int i; 
Console.WriteLine{"{0}",i); 

技術的には、上記問題ないはずです - しかし、それは、プログラマのエラーの一般的なソースだから、コンパイラは特に割り当てられていないローカル変数のためにチェックし、文句を言います。ただし、これはコンパイル時の苦情であり、CLRの問題ではありません。あなたは上記を行うILを作ることができ、うまく動作します。

0

これらのフィールド(クラス変数)のためにのみ等価です。クラスが初期化されると、フィールドには自動的にデフォルト値が割り当てられます。メソッドまたはプロパティ内で、割り当てられていない変数は未割り当てのままになり、その値にアクセスしようとするとコンパイラエラーが発生します。

1

この話は、C#の "default"キーワードに言及する価値があります。

I.e. int i;int i = 0;MyClass o = default(MyClass);に相当するint i = default(int);と等価であることは、このような.SingleOrDefault()としてLINQのメソッドを使用しているときは、常にあなたのコードを読みやすくするために、以下を使用することができますので、これは特に関連性があるMyClass o = null;

と同等です:

int someValue = collection.<various linq methods>.SingleOrDefault(); 
if (someValue == default(int)) 
{ 
    //Code for the default case 
} 
ここ

MyClass someValue = collection.<various linq methods>.SingleOrDefault(); 
if (someValue == default(MyClass)) 
{ 
    //Code for the default case 
} 
0

様々な応答が目を含め、一種の誤解を招くようですe「Coding Horror」のウェブサイトを参照してください。

コンパイラは、生成されたコードを最適化するように構成されている場合、すべての「不要な」初期化を削除するようにコードを最適化します。これは "リリース"モードでコンパイルするときのデフォルトの動作であることに注意してください。

私は、すべての変数を初期化することは常に非常に有用だと考えています。パフォーマンス・ヒットはデバッグ・モードでは最小限になり、リリース・モードでは最小限に抑えられますが、明示的に設定された利得は、今後コードを保守するすべての人にとって、「コード付きのコードを記述する」スタイルでは非常に大きくなります。私はInt32のデフォルト値が0ではなくInt32.MinValueであると思っていたこの非常に経験豊富な同僚を覚えています。これらのタイプの混乱は、コードに暗示されている事柄に常に起こり、私にとってはほとんどの場合避けるべきです。