37

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ていません。

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

4

1 に答える 1

51

この構文は、オブジェクトの初期化と呼ばれます。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; }
}

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

于 2013-05-28T14:48:19.347 に答える