これら2つの違いは何ですか?
class Class1
{
public int a = 1;
}
class Class2
{
public int a;
public Class2()
{
a = 1;
}
}
ない場合、デフォルトのコンストラクターをスキップして、のように変数を初期化できますClass1
か?
これら2つの違いは何ですか?
class Class1
{
public int a = 1;
}
class Class2
{
public int a;
public Class2()
{
a = 1;
}
}
ない場合、デフォルトのコンストラクターをスキップして、のように変数を初期化できますClass1
か?
各クラスの IL でわかるように、違いはコンストラクター呼び出しと「a」フィールド設定の順序にあります。
クラス1
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldc.i4.1
IL_0002: stfld int32 SandBox.Class1::a
IL_0007: ldarg.0
IL_0008: call instance void [mscorlib]System.Object::.ctor()
IL_000d: ret
クラス2
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: ldarg.0
IL_0007: ldc.i4.1
IL_0008: stfld int32 SandBox.Class2::a
IL_000d: ret
特定の例では、フィールド初期化子 ( Class1
) は問題ありません。おそらく、問題ないのは public フィールドです ;p 次のいずれかをお勧めします:
// manually implemented property with field-initializer
private int a = 1;
public int A { get { return a;} set { a = value;} }
また:
// automatically implemented property with constructor-based initialization
public int A {get;set;}
public Class1() {
A = 1;
}
@hvdの答えは違いを正しく述べています。これにより異なる結果が得られる具体的な例を示すには、次を参照してください。virtual
この例から得られる主なメッセージは、「コンストラクターからメソッドを使用するときは非常に注意してください」ということです。
最初に出力:
Class1: 1
Class2: 0
コード:
using System;
abstract class SomeBaseClass {
protected abstract void Write();
protected SomeBaseClass() {
Console.Write(GetType().Name + ": ");
Write();
}
}
class Class1 : SomeBaseClass {
protected override void Write() {
Console.WriteLine(a);
}
public int a = 1;
}
class Class2 : SomeBaseClass {
protected override void Write() {
Console.WriteLine(a);
}
public int a;
public Class2() {
a = 1;
}
}
static class Program {
static void Main() {
new Class1();
new Class2();
}
}