2つの違いは何ですか?また、いつ「コンストラクター」よりも「オブジェクト初期化子」を使用し、その逆を使用しますか? それが重要な場合、私はC#で作業しています。また、オブジェクト初期化メソッドは C# または .NET に固有のものですか?
7 に答える
オブジェクト初期化子は、オブジェクトを使用しているときにオブジェクトの構築を簡素化するために、C# 3 に追加されたものです。
コンストラクターは、0 個以上のパラメーターを指定して実行され、呼び出し元のメソッドが作成されたオブジェクトへのハンドルを取得する前に、オブジェクトを作成および初期化するために使用されます。例えば:
MyObject myObjectInstance = new MyObject(param1, param2);
この場合、 のコンストラクターはMyObject
値param1
およびで実行されますparam2
。これらは両方ともMyObject
、メモリ内に新しいものを作成するために使用されます。作成されたオブジェクト (これらのパラメーターを使用してセットアップされます) が返され、 に設定されmyObjectInstance
ます。
一般に、オブジェクトを完全にセットアップするために必要なパラメーターをコンストラクターに要求させることをお勧めします。これにより、無効な状態でオブジェクトを作成することはできなくなります。
ただし、多くの場合、設定できる「追加の」プロパティがありますが、必須ではありません。これは、オーバーロードされたコンストラクターを使用して処理できますが、ほとんどの状況で必ずしも有用ではない多くのコンストラクターを持つことになります。
これはオブジェクト初期化子につながります - オブジェクト初期化子を使用すると、オブジェクトが構築された後、他のオブジェクトで使用できるようになる前に、オブジェクトにプロパティまたはフィールドを設定できます。例えば:
MyObject myObjectInstance = new MyObject(param1, param2)
{
MyProperty = someUsefulValue
};
これは、これを行う場合とほぼ同じように動作します。
MyObject myObjectInstance = new MyObject(param1, param2);
myObjectInstance.MyProperty = someUsefulValue;
ただし、マルチスレッド環境では、オブジェクト初期化子のアトミック性が有益な場合があります。オブジェクトが完全に初期化されていない状態になるのを防ぐためです (詳細については、この回答を参照してください)。意図したように null または初期化されます。
また、オブジェクト初期化子は読みやすく (特に複数の値を設定する場合)、そのクラスの API を複雑にする多くのオーバーロードを必要とせずに、コンストラクターの多くのオーバーロードと同じ利点を提供します。
コンストラクターは、指定された数のパラメーターを取り、オブジェクトの作成と初期化に使用される型の定義済みメソッドです。
オブジェクト初期化子は、コンストラクターの後にオブジェクトで実行されるコードであり、オブジェクトの任意の数のフィールドを指定された値に簡潔に設定するために使用できます。これらのフィールドの設定は、コンストラクターが呼び出された 後に発生します。
コンストラクターがオブジェクトの初期状態を十分に設定する場合、オブジェクト初期化子の助けを借りずにコンストラクターを使用します。ただし、オブジェクト初期化子はコンストラクターと組み合わせて使用する必要があります。この構文では、コンストラクターを明示的または暗黙的に使用 (VB.Net および C#) して初期オブジェクトを作成する必要があります。コンストラクターがオブジェクトを十分に初期化せず、いくつかの単純なフィールドおよび/またはプロパティ セットが必要な場合は、オブジェクト初期化子を使用します。
あなたがするとき
Person p = new Person { Name = "a", Age = 23 };
これは、オブジェクト初期化子が本質的に行うことです。
Person tmp = new Person(); //creates temp object calling default constructor
tmp.Name = "a";
tmp.Age = 23;
p = tmp;
これにより、このような動作が容易になります。オブジェクト初期化子がどのように機能するかを知ることは重要です。
オブジェクトが正しく機能するために設定しなければならないプロパティがある場合、1 つの方法は、これらの必須プロパティをパラメーターとして必要とする単一のコンストラクターのみを公開することです。
その場合、これらの必須プロパティを指定せずにオブジェクトを作成することはできません。そのようなものは、オブジェクト初期化子によって強制することはできません。
オブジェクト初期化子は、実際には、初期割り当てを短縮するための「構文上の利便性」にすぎません。素晴らしいですが、機能的にはあまり関係ありません。
マルク
コンストラクターは、(おそらく) パラメーターを受け取り、クラスの新しいインスタンスを返すメソッドです。初期化ロジックが含まれている場合があります。以下に、コンストラクターの例を示します。
public class Foo
{
private SomeClass s;
public Foo(string s)
{
s = new SomeClass(s);
}
}
次の例を考えてみましょう。
public class Foo
{
public SomeClass s { get; set; }
public Foo() {}
}
次のコードで SomeClass にアクセスできると仮定すると、オブジェクト初期化子を使用して最初の例と同じ結果を得ることができます。
new Foo() { s = new SomeClass(someString) }
ご覧のとおり、オブジェクト初期化子を使用すると、構築が実行されると同時にパブリック フィールドとパブリック (設定可能) プロパティの値を指定できます。これは、コンストラクターが特定のフィールドを初期化するオーバーロードを提供しない場合に特に役立ちます。ただし、オブジェクト初期化子は単なる構文糖衣であり、コンパイル後は一連の代入と実際には変わらないことに注意してください。