PG日誌

各記事はブラウザの横幅を1410px以上にすると2カラムの見出しが表示されます。なるべく横に広げてみてください。

C#でオブジェクト初期化子を使った時の丸カッコの有無

C#には「オブジェクト初期化子」というインスタンス作成時に使用できる初期化方法があります。

例えば以下のようなクラスがあった場合、公開されているプロパティに対して初期化と同時に値が設定できます。

// クラス宣言
public class Point2Di
{
    public int X { get; set; }
    public int Y { get; set; }
}

// オブジェクト初期化子による初期化
var p = new Point2Di
{
    X = 10,
    Y = 20 // プロパティに対して作成と同時に値の設定ができる
};

また配列やコレクションの初期化を行うことができます。

var list = new List<int>
{
   1, 2, 3, 4, 5
};

var array = new int[] { 1, 3, 5, 7 };

この機能でリストの初期化やコンストラクターに引数が含まれないフィールドを作成と同時に初期化することができます。

で、この初期化子ですが以下のように2種類書き方があります。

// (1) オブジェクト初期化子で初期化。【丸カッコ付き】
var p2 = new Point2Di()
{
    X = -3,
    //Y = -4
};

// (2) オブジェクト初期化子で初期化。【丸カッコ無し】
var p3 = new Point2Di
{
    X = -5,
    //Y = -6,
};

何が言いたいのかと言いうと、このカッコの有無で挙動の違いはありません。

動作確認

動作に差異が無いことを確認するために冒頭のクラスでコンストラクタが呼び出されるとログが出力されるようにコンストラクターを追加します。

public class Point2Di
{
    public int X { get; set; }
    public int Y { get; set; }

    // 呼び出されるとログが出る
    public Point2Di() => Console.WriteLine("ctor");
}

次に以下コードを実行します。

// 確認用のコード

// (1) オブジェクト初期化子で初期化。【丸カッコ付き】
var p1 = new Point2Di()
{
    X = -3,
    //Y = -4
};
// 出力:
//> ctor

// (2) オブジェクト初期化子で初期化。【丸カッコ無し】
var p2 = new Point2Di
{
    X = -5,
    //Y = -6,
};
// 出力:
//> ctor

//Console.WriteLine($"p1({p1.X}, {p1.Y})");
Console.WriteLine($"p1({p1.X}, {p1.Y})");
Console.WriteLine($"p2({p2.X}, {p2.Y})");
// 出力:
//> p1(-3, 0)
//> p2(-5, 0)
//  → 結果は同じ

それぞれで、(1) コンストラクターが呼び出される → (2) メンバーは規定値に初期化される → (3) メンバー初期化子の内容がオブジェクトに設定されるという挙動が同じことが確認できたと思います。

以上です。