次のような整数変数を初期化するかどうかに違いはありますか:
int i = 0;
int i;
コンパイラまたは CLR はこれを同じものとして扱いますか? IIRC、どちらも同じものとして扱われていると思いますが、記事が見つからないようです。
次のような整数変数を初期化するかどうかに違いはありますか:
int i = 0;
int i;
コンパイラまたは CLR はこれを同じものとして扱いますか? IIRC、どちらも同じものとして扱われていると思いますが、記事が見つからないようです。
変数iがインスタンス変数の場合、値 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 に 0 を割り当てると、つまり
int i2 = 0;
コンパイルしてから実行すると、両方に 0 が割り当てられていることがわかります。
(ildasm を使用して) IL を調べたところ、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
はい、ほとんど同じです。
コーディングホラーに関するこの記事を参照できます
このすべての話で、C#の「デフォルト」キーワードに言及する価値があります。
つまり、とint i;
同等int i = default(int);
でint i = 0;
あり、MyClass o = default(MyClass);
と同等ですMyClass o = null;
これは、次のようなlinqメソッドを使用する場合に特に関係があります。これは.SingleOrDefault()
、コードを読みやすくするために常に次のコマンドを使用できるためです。
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
}
ここでのさまざまな応答は、「コーディングホラー」Webサイトの参照記事を含め、誤解を招くようなものです。
コンパイラーは、生成されたコードを最適化するように構成されている場合、コードを最適化して「不要な」初期化をすべて削除します。これは、「リリース」モードでコンパイルするときのデフォルトの動作であることに注意してください。
私は、たとえば、すべての変数を初期化することは常に非常に役立つと思います。パフォーマンスへの影響は、デバッグモードでは最小限に抑えられ、リリースモードでは発生しませんが、変数を明示的に設定することで、将来、より優れた「コードを使用したコードの文書化」スタイルでコードを保守する人にとっては大きなメリットがあります。Int32のデフォルト値は0ではなくInt32.MinValueであると考えていた、この非常に経験豊富な同僚のことを覚えています。これらのタイプの混乱は、コードに暗黙的に含まれているものに常に発生し、私にとっては、ほとんどの場合回避する必要があります。
次のリンクが示すように、それらはまったく同じです。
http://msdn.microsoft.com/en-us/library/aa664742%28VS.71%29.aspx
C# で型を作成すると、自動的にゼロが埋め込まれます。クラス (参照型) の場合、これは null ポインターに相当します。したがって、技術的には、クラスを操作するときはいつでも、以下は同じです。
MyClass class;
MyClass class2 = null;
値型 (int/float/double/etc を含む任意の構造体) では、型はゼロで渡されるため、以下は同等です。
int i;
int j = 0;
ただし、メソッドでは、コンパイラは、値を使用する前に型に値が割り当てられているかどうかを確認します。次のようにすると、コンパイラは文句を言います。
int i;
Console.WriteLine{"{0}",i);
技術的には、上記は問題ないはずですが、これはプログラマーのエラーの一般的な原因であるため、コンパイラーは割り当てられていないローカル変数を明確にチェックし、文句を言います。ただし、これはコンパイル時の問題であり、CLR の問題ではありません。上記を行うILを作成でき、正常に動作します。
これらは、フィールド (クラス変数) に対してのみ同等です。クラスが初期化されると、フィールドには自動的にデフォルト値が割り当てられます。メソッドまたはプロパティ内では、割り当てられていない変数は割り当てられていないままであり、その値にアクセスしようとするとコンパイラ エラーが発生します。