How to: Infer Property Names and Types in Anonymous Type Declarations (Visual Basic)
Anonymous types provide no mechanism for directly specifying the data types of properties. Types of all properties are inferred. In the following example, the types of Name
and Price
are inferred directly from the values that are used to initialize them.
' Variable product is an instance of a simple anonymous type.
Dim product = New With {Key .Name = "paperclips", .Price = 1.29}
Anonymous types can also infer property names and types from other sources. The sections that follow provide a list of the circumstances where inference is possible, and examples of situations where it is not.
Successful Inference
Anonymous types can infer property names and types from the following sources:
From variable names. Anonymous type
anonProduct
will have two properties,productName
andproductPrice
. Their data types will be those of the original variables,String
andDouble
, respectively.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}
From property or field names of other objects. For example, consider a
car
object of aCarClass
type that includesName
andID
properties. To create a new anonymous type instance,car1
, withName
andID
properties that are initialized with the values from thecar
object, you can write the following:Dim car1 = New With {Key car.Name, Key car.ID}
The previous declaration is equivalent to the longer line of code that defines anonymous type
car2
.Dim car2 = New With {Key .Name = car.Name, Key .ID = car.ID}
From XML member names.
Dim books = <Books> <Book Author="Jesper Aaberg"> Advanced Programming Methods </Book> </Books> Dim anon = New With {books...<Book>}
The resulting type for
anon
would have one property,Book
, of type IEnumerable(Of XElement).From a function that has no parameters, such as
SomeFunction
in the following example.Dim sc As New SomeClass Dim anon1 = New With {Key sc.SomeFunction()}
The variable
anon2
in the following code is an anonymous type that has one property, a character namedFirst
. This code will display a letter "E," the letter that is returned by function 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)
Inference Failures
Name inference will fail in many circumstances, including the following:
The inference derives from the invocation of a method, a constructor, or a parameterized property that requires arguments. The previous declaration of
anon1
fails ifsomeFunction
has one or more arguments.' Not valid. ' Dim anon3 = New With {Key sc.someFunction(someArg)}
Assignment to a new property name solves the problem.
' Valid. Dim anon4 = New With {Key .FunResult = sc.someFunction(someArg)}
The inference derives from a complex expression.
Dim aString As String = "Act " ' Not valid. ' Dim label = New With {Key aString & "IV"}
The error can be resolved by assigning the result of the expression to a property name.
' Valid. Dim label1 = New With {Key .someLabel = aString & "IV"}
Inference for multiple properties produces two or more properties that have the same name. Referring back to declarations in earlier examples, you cannot list both
product.Name
andcar1.Name
as properties of the same anonymous type. This is because the inferred identifier for each of these would beName
.' Not valid. ' Dim anon5 = New With {Key product.Name, Key car1.Name}
The problem can be solved by assigning the values to distinct property names.
' Valid. Dim anon6 = New With {Key .ProductName = product.Name, Key .CarName = car1.Name}
Note that changes in case (changes between uppercase and lowercase letters) do not make two names distinct.
Dim price = 0 ' Not valid, because Price and price are the same name. ' Dim anon7 = New With {Key product.Price, Key price}
The initial type and value of one property depends on another property that is not yet established. For example,
.IDName = .LastName
is not valid in an anonymous type declaration unless.LastName
is already initialized.' Not valid. ' Dim anon8 = New With {Key .IDName = .LastName, Key .LastName = "Jones"}
In this example, you can fix the problem by reversing the order in which the properties are declared.
' Valid. Dim anon9 = New With {Key .LastName = "Jones", Key .IDName = .LastName}
A property name of the anonymous type is the same as the name of a member of Object. For example, the following declaration fails because
Equals
is a method of Object.' Not valid. ' Dim relationsLabels1 = New With {Key .Equals = "equals", Key .Greater = _ ' "greater than", Key .Less = "less than"}
You can fix the problem by changing the property name:
' Valid Dim relationsLabels2 = New With {Key .EqualString = "equals", Key .GreaterString = "greater than", Key .LessString = "less than"}