次の方法で共有


オブジェクト初期化子: 名前付き型と匿名型 (Visual Basic)

オブジェクト初期化子を使用すると、1 つの式を使用して複合オブジェクトのプロパティを指定できます。 名前付き型と匿名型のインスタンスを作成するために使用できます。

宣言

名前付き型と匿名型のインスタンスの宣言はほぼ同じように見えますが、その効果は同じではありません。 各カテゴリには、独自の機能と制限があります。 次の例は、オブジェクト初期化子リストを使用して、名前付きクラス ( Customer) のインスタンスを宣言および初期化する便利な方法を示しています。 キーワード Newの後にクラスの名前が指定されていることに注意してください。

Dim namedCust = New Customer With {.Name = "Terry Adams"}

匿名型には使用可能な名前がありません。 したがって、匿名型のインスタンス化にはクラス名を含めることはできません。

Dim anonymousCust = New With {.Name = "Hugo Garcia"}

2 つの宣言の要件と結果は同じではありません。 namedCustの場合、Name プロパティを持つCustomer クラスが既に存在する必要があり、宣言によってそのクラスのインスタンスが作成されます。 anonymousCustの場合、コンパイラは 1 つのプロパティを持つ新しいクラス、Nameという文字列を定義し、そのクラスの新しいインスタンスを作成します。

名前付き型

オブジェクト初期化子は、型のコンストラクターを呼び出し、1 つのステートメントで一部またはすべてのプロパティの値を設定する簡単な方法を提供します。 コンパイラは、ステートメントに適したコンストラクター (引数が指定されていない場合はパラメーターなしのコンストラクター)、1 つ以上の引数が送信された場合はパラメーター化されたコンストラクターを呼び出します。 その後、指定したプロパティは初期化子リストに表示される順序で初期化されます。

初期化子リスト内の各初期化は、クラスのメンバーへの初期値の割り当てで構成されます。 メンバーの名前とデータ型は、クラスが定義されるときに決定されます。 次の例では、 Customer クラスが存在し、文字列値を受け入れることができる Name および City という名前のメンバーが必要です。

Dim cust0 As Customer = New Customer With {.Name = "Toni Poe", 
                                           .City = "Louisville"}

または、次のコードを使用して同じ結果を取得することもできます。

Dim cust1 As New Customer With {.Name = "Toni Poe", 
                                .City = "Louisville"}

これらの各宣言は、パラメーターなしのコンストラクターを使用してCustomer オブジェクトを作成し、With ステートメントを使用してNameプロパティとCityプロパティの初期値を指定する次の例と同じです。

Dim cust2 As New Customer()
With cust2
    .Name = "Toni Poe"
    .City = "Louisville"
End With

たとえば、 Customer クラスにパラメーター化されたコンストラクターが含まれており、 Nameの値を送信できる場合は、次の方法で Customer オブジェクトを宣言および初期化することもできます。

Dim cust3 As Customer = 
    New Customer("Toni Poe") With {.City = "Louisville"}
' --or--
Dim cust4 As New Customer("Toni Poe") With {.City = "Louisville"}

次のコードに示すように、すべてのプロパティを初期化する必要はありません。

Dim cust5 As Customer = New Customer With {.Name = "Toni Poe"}

ただし、初期化リストを空にすることはできません。 初期化されていないプロパティは既定値を保持します。

名前付き型を使用した型の推論

オブジェクト初期化子とローカル型推論を組み合わせることにより、 cust1 の宣言のコードを短縮できます。 これにより、変数宣言で As 句を省略できます。 変数のデータ型は、代入によって作成されたオブジェクトの型から推論されます。 次の例では、 cust6 の種類が Customer

Dim cust6 = New Customer With {.Name = "Toni Poe", 
                               .City = "Louisville"}

名前付き型に関する解説

  • クラス メンバーは、オブジェクト初期化子リスト内で複数回初期化できません。 cust7の宣言によってエラーが発生します。

    '' This code does not compile because Name is initialized twice.
    ' Dim cust7 = New Customer With {.Name = "Toni Poe", 
    '                                .City = "Louisville",
    '                                .Name = "Blue Yonder Airlines"}
    
  • メンバーは、それ自体または別のフィールドを初期化するために使用できます。 cust8の次の宣言のように、メンバーが初期化される前にアクセスされた場合、既定値が使用されます。 オブジェクト初期化子を使用する宣言が処理されるときに最初に発生するのは、適切なコンストラクターが呼び出されるということです。 その後、初期化子リスト内の個々のフィールドが初期化されます。 次の例では、 Name の既定値が cust8に割り当てられ、初期化された値が cust9で割り当てられます。

    Dim cust8 = New Customer With {.Name = .Name & ", President"}
    Dim cust9 = New Customer With {.Name = "Toni Poe", 
                                   .Title = .Name & ", President"}
    

    次の例では、 cust3 および cust4 のパラメーター化されたコンストラクターを使用して、 cust10cust11を宣言および初期化します。

    Dim cust10 = New Customer("Toni Poe") With {.Name = .Name & ", President"}
    ' --or--
    Dim cust11 As New Customer("Toni Poe") With {.Name = .Name & ", President"}
    
  • オブジェクト初期化子は入れ子にすることができます。 次の例では、AddressClassCityState の 2 つのプロパティを持つクラスであり、Customer クラスにはAddressClassのインスタンスであるAddress プロパティがあります。

    Dim cust12 = 
        New Customer With {.Name = "Toni Poe", 
                           .Address = 
                               New AddressClass With {.City = "Louisville", 
                                                      .State = "Kentucky"}}
    Console.WriteLine(cust12.Address.State)
    
  • 初期化リストを空にすることはできません。

  • 初期化中のインスタンスを Object 型にすることはできません。

  • 初期化されるクラス メンバーは、共有メンバー、読み取り専用メンバー、定数、またはメソッド呼び出しにすることはできません。

  • 初期化中のクラス メンバーにインデックスを作成したり、修飾したりすることはできません。 次の例では、コンパイラ エラーが発生します。

    '' Not valid.

    ' Dim c1 = New Customer With {.OrderNumbers(0) = 148662}

    ' Dim c2 = New Customer with {.Address.City = "Springfield"}

匿名型

匿名型では、オブジェクト初期化子を使用して、明示的に定義および名前を付けなかった新しい型のインスタンスを作成します。 代わりに、コンパイラは、オブジェクト初期化子リストで指定したプロパティに従って型を生成します。 型の名前が指定されていないため、 匿名型と呼ばれます。 たとえば、次の宣言を、 cust6の前の宣言と比較します。

Dim cust13 = New With {.Name = "Toni Poe", 
                       .City = "Louisville"}

構文的に唯一の違いは、データ型の New 後に名前が指定されないということです。 しかし、何が起こるかはまったく異なります。 コンパイラは、 NameCityの 2 つのプロパティを持つ新しい匿名型を定義し、指定された値を持つインスタンスを作成します。 型推論により、例の NameCity の型が文字列になります。

注意事項

匿名型の名前はコンパイラによって生成され、コンパイルによって異なる場合があります。 コードでは、匿名型の名前を使用したり、依存したりしないでください。

型の名前は使用できないため、 As 句を使用して cust13を宣言することはできません。 その型を推論する必要があります。 遅延バインディングを使用しない場合、匿名型の使用はローカル変数に制限されます。

匿名型は、LINQ クエリの重要なサポートを提供します。 クエリでの匿名型の使用の詳細については、「 匿名 型」および 「Visual Basic での LINQ の概要」を参照してください。

匿名型に関する解説

  • 通常、匿名型宣言のプロパティのすべてまたは大部分がキー プロパティになります。キー プロパティは、プロパティ名の前にキーワード Key を入力することによって示されます。

    
    Dim anonymousCust1 = New With {Key .Name = "Hugo Garcia", 
                                   Key .City = "Louisville"}
    

    キーのプロパティの詳細については、「 キー」を参照してください。

  • 名前付き型と同様に、匿名型定義の初期化子リストでは、少なくとも 1 つのプロパティを宣言する必要があります。

    Dim anonymousCust = New With {.Name = "Hugo Garcia"}
    
  • 匿名型のインスタンスが宣言されると、コンパイラは一致する匿名型定義を生成します。 プロパティの名前とデータ型は、インスタンス宣言から取得され、コンパイラによって定義に含まれます。 名前付き型の場合と同様に、プロパティは名前付きではなく、事前に定義されています。 それらの型が推論されます。 As句を使用してプロパティのデータ型を指定することはできません。

  • 匿名型は、他のいくつかの方法でプロパティの名前と値を確立することもできます。 たとえば、匿名型プロパティは、変数の名前と値、または別のオブジェクトのプロパティの名前と値の両方を受け取ることができます。

    ' Create a variable, Name, and give it an initial value.
    Dim Name = "Hugo Garcia"
    
    ' Variable anonymousCust2 will have one property, Name, with 
    ' "Hugo Garcia" as its initial value.
    Dim anonymousCust2 = New With {Key Name}
    
    ' The next declaration uses a property from namedCust, defined
    ' in an earlier example. After the declaration, anonymousCust3 will
    ' have one property, Name, with "Terry Adams" as its value.
    Dim anonymousCust3 = New With {Key namedCust.Name}
    

    匿名型でプロパティを定義するためのオプションの詳細については、「 方法: 匿名型宣言でプロパティ名と型を推論する」を参照してください。

こちらも参照ください