web-dev-qa-db-ja.com

ネストされたオブジェクト初期化構文

Resharperは、次のリファクタリングを提案しました。

// Constructor initializes InitializedProperty but
// the UninitializedSubproperty is uninitialized.
var myInstance = new MyClass();
myInstance.InitializedProperty.UninitializedSubproperty = new MyOtherClass();

// becomes

var myInstance = new MyClass
    {
        InitializedProperty = { UninitializedSubproperty = new MyOtherClass() }
    };

この種のオブジェクトの初期化はこれまで見たことがありません。特に私は方法がわかりません

InitializedProperty = { UninitializedSubproperty = new MyOtherClass() }

意味があります-そうではありません割り当てInitializedPropertyには何もありません。

この動作はどこかに指定されていますか?

28
Rawling

この構文は オブジェクト初期化 と呼ばれます。 C#仕様は、このテーマに関する多くの例を明確に示しています。

7.6.10.2オブジェクト初期化子

オブジェクト初期化子は、{および}トークンで囲まれ、コンマで区切られた一連のメンバー初期化子で構成されます。各メンバー初期化子は、初期化されるオブジェクトのアクセス可能なフィールドまたはプロパティに名前を付け、その後に等号と式、またはオブジェクト初期化子またはコレクション初期化子を指定する必要があります。オブジェクト初期化子が同じフィールドまたはプロパティに複数のメンバー初期化子を含めることはエラーです。オブジェクト初期化子が、初期化する新しく作成されたオブジェクトを参照することはできません。

例は次のとおりです。

Rectangle r = new Rectangle
            {
                P1 = { X = 0, Y = 1 },
                P2 = { X = 2, Y = 3 }
            };

以下にコンパイルされます:

Rectangle r = new Rectangle();
r.P1.X = 0;
r.P1.Y = 1;
r.P2.X = 2;
r.P2.Y = 3;

持っている:

public class Rectangle
{
    public Rectangle()
    {
        P1 = new Point(); //default Point for demo purpose
        P2 = new Point(); //default Point for demo purpose
    }

    public Point P1 { get; set; }
    public Point P2 { get; set; }
}

そして

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

また、C#の詳細の本のすばらしい章8.3簡略化された初期化を読むことを検討してください。 Jon Skeetは、ツリーのような構造を初期化するためにこの種の構文を使用することの利点について別の見方をしています。

41
Ilya Ivanov