方法: 匿名型の宣言におけるプロパティ名と型を推論する (Visual Basic)

匿名型には、プロパティのデータ型を直接指定する機構はありません。 すべてのプロパティの型は、推論されます。 次の例では、 NamePrice の型は、それらを初期化するために使われる値から、直接推論されます。

' Variable product is an instance of a simple anonymous type.
Dim product = New With {Key .Name = "paperclips", .Price = 1.29}

匿名型は、プロパティの名前と型を、他のソースから推論することもできます。 この後のセクションで、推論が可能な状況の一覧と、推論が行われない状況の例を示します。

正常な推論

匿名型は、プロパティの名前と型を、次のソースから推論できます:

  • 変数名から。 匿名型 anonProduct には、 productNameproductPriceという 2 つのプロパティがあります。 それらのプロパティのデータ型は、それぞれ、元の変数のデータ型である StringDoubleになります。

    Dim productName As String = "paperclips"
    Dim productPrice As Double = 1.29
    Dim anonProduct = New With {Key productName, Key productPrice}
    
    ' To create uppercase variable names for the new properties,
    ' assign variables productName and productPrice to uppercase identifiers.
    Dim anonProduct1 = New With {Key .Name = productName, Key .Price = productPrice}
    
  • 他のオブジェクトのプロパティまたはフィールドの名前から。 たとえば、 car プロパティと CarClass プロパティを含む Name 型の ID オブジェクトがあるとします。 新しい匿名型のインスタンス car1を作成し、 Name オブジェクトの値を使用して ID プロパティと car プロパティを初期化するには、次のように記述できます。

    Dim car1 = New With {Key car.Name, Key car.ID}
    

    前の宣言は、匿名型 car2を定義する、次の長いコードに相当します。

    Dim car2 = New With {Key .Name = car.Name, Key .ID = car.ID}
    
  • XML メンバー名から。

    Dim books = <Books>
                    <Book Author="Jesper Aaberg">
                        Advanced Programming Methods
                    </Book>
                </Books>
    Dim anon = New With {books...<Book>}
    

    推論後の anon の型は、 Book(Of XElement) 型の 1 つのプロパティ IEnumerableを持ちます。

  • 次の例に示す SomeFunction など、パラメーターを持たない関数から。

    Dim sc As New SomeClass
    Dim anon1 = New With {Key sc.SomeFunction()}
    

    次のコードの anon2 変数は、 Firstという名前の 1 文字を表すプロパティを 1 つ持つ匿名型です。 このコードでは、文字 "E" が表示されます。これは関数 Firstから返される文字です。

    Dim aString As String = "Example String"
    Dim anon2 = New With {Key aString.First()}
    ' The variable anon2 has one property, First.
    Console.WriteLine(anon2.First)
    

推論の失敗

名前の推論は、次の状況を含む、さまざまな状況で失敗します:

  • 推論が、引数を必要とするメソッド、コンストラクター、またはパラメーター化されたプロパティの呼び出しから派生する場合。 前の anon1 の宣言は、 someFunction に 1 つ以上の引数があると失敗します。

    ' Not valid.
    ' Dim anon3 = New With {Key sc.someFunction(someArg)}
    

    この問題は、新しいプロパティ名を割り当てることによって解決できます。

    ' Valid.
    Dim anon4 = New With {Key .FunResult = sc.someFunction(someArg)}
    
  • 推論が、複合式から派生する場合。

    Dim aString As String = "Act "
    ' Not valid.
    ' Dim label = New With {Key aString & "IV"}
    

    このエラーは、式の結果をプロパティ名に割り当てれば解決できます。

    ' Valid.
    Dim label1 = New With {Key .someLabel = aString & "IV"}
    
  • 複数のプロパティの推論で、同じ名前を持つ 2 つ以上のプロパティが生成される場合。 前の例で示した宣言で説明すると、同じ匿名型のプロパティとして product.Namecar1.Name の両方を指定することはできません。 これは、各プロパティの推論された識別子がどちらも Nameになるためです。

    ' Not valid.
    ' Dim anon5 = New With {Key product.Name, Key car1.Name}
    

    この問題は、別個のプロパティ名に値を割り当てることで解決できます。

    ' Valid.
    Dim anon6 = New With {Key .ProductName = product.Name, Key .CarName = car1.Name}
    

    大文字と小文字の違いでは、別個の名前にならないことにご注意ください。

    Dim price = 0
    ' Not valid, because Price and price are the same name.
    ' Dim anon7 = New With {Key product.Price, Key price}
    
  • 1 つのプロパティの初期の型と値が、まだ確立されていない別のプロパティに依存している場合。 たとえば、 .IDName = .LastName は、 .LastName が既に初期化されていない限り、匿名型の宣言では使えません。

    ' Not valid.
    ' Dim anon8 = New With {Key .IDName = .LastName, Key .LastName = "Jones"}
    

    この例では、プロパティを宣言する順序を逆にすることで、問題を修正できます。

    ' Valid.
    Dim anon9 = New With {Key .LastName = "Jones", Key .IDName = .LastName}
    
  • 匿名型のプロパティの名前が、 Objectのメンバーの名前と同じである場合。 たとえば、次の宣言は、 EqualsObjectのメソッドなので失敗します。

    ' Not valid.
    ' Dim relationsLabels1 = New With {Key .Equals = "equals", Key .Greater = _
    '                       "greater than", Key .Less = "less than"}
    

    この問題は、プロパティ名を変更することで修正できます。

    ' Valid 
    Dim relationsLabels2 = New With {Key .EqualString = "equals",
                                     Key .GreaterString = "greater than",
                                     Key .LessString = "less than"}
    

関連項目