3

これら2つの違いは何ですか?

class Class1
{
    public int a = 1;
}

class Class2
{
    public int a;
    public Class2()
    {
        a = 1;
    }
}

ない場合、デフォルトのコンストラクターをスキップして、のように変数を初期化できますClass1か?

4

5 に答える 5

3

各クラスの 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
于 2013-05-20T14:01:35.353 に答える
1

特定の例では、フィールド初期化子 ( 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();
    }
}
于 2013-05-20T13:58:45.523 に答える