Object and Collection Initializers - VB

[Table of Contents] [Next Topic]

Object are a VB 9.0 feature that allows you to create objects in an expression context instead of in a statement context.  Sometimes this is called in-line initialization of objects.

When doing FP, we want to create tuples (next topic), and we sometimes want to use object initializers in order to do this.

This blog is inactive.
New blog: EricWhite.com/blog

Blog TOCIt is very convenient and much more readable to create object collections/graphs/trees using object initializers.

Terms to Understand

There are a few important terms to understand for this discussion. If we define these terms, it will make it much easier to talk about object initialization.

Object Graph

An object graph is a number of VB objects that are tied together in some significant way. For example, you might create a Rectangle object, which contains multiple Point objects:

Class Point
Private m_x, m_y As Integer
Public Property X As Integer
Get
Return m_x
End Get
Set(ByVal value As Integer)
m_x = value
End Set
End Property
Public Property Y As Integer
Get
Return m_y
End Get
Set(ByVal value As Integer)
m_y = value
End Set
End Property
End Class

Class Rectangle
Private m_p1 As Point
Private m_p2 As Point
Public Property P1 As Point
Get
Return m_p1
End Get
Set
m_p1 = Value
End Set
End Property
Public Property P2 As Point
Get
Return m_p2
End Get
Set
m_p2 = Value
End Set
End Property
End Class

You would typically create an object graph as follows:

Dim r As Rectangle = New Rectangle
r.P1 = New Point
r.P1.X = 1
r.P1.Y = 2
r.P2 = New Point
r.P2.X = 3
r.P2.Y = 4

Statement Context vs. Expression Context

An important idea to understand here is the difference between statement context and expression context.  A statement context is one where the compiler expects and can parse a statement.  An expression context is much more limited.  As an example, you can pass an expression as an argument to a method, but you are not allowed to write a complete statement where an argument is expected.

Creation of Object Hierarchies in an Expression Context

One of the most important characteristics of object initializers is that it allows you to create an entire object hierarchy in an expression context instead of a statement context.

The above object hierarchy could only be initialized in a context where statements are allowed, such as in the body of a method, or maybe when initializing a member variable.

An expression context can be found anywhere in the language where you are allowed to write an expression.  If you need to pass an object hierarchy as an argument to a method, previously, you needed to create the objects, and then pass the root object to the method.  In contrast, with VB 9.0 you can new up the objects in-line as a parameter to the method.

The Simplest Object Initializer

The best way to understand object initializers is to start with the simplest, easiest case and progress from there.

If we have a class Person, as follows:

Class Person
Dim m_name As String
Dim m_age As Integer
Dim m_canCode As Boolean
Public Property Name As String
Get
Return m_name
End Get
Set(ByVal value As String)
m_name = value
End Set
End Property
Public Property Age As Integer
Get
Return m_age
End Get
Set(ByVal value As Integer)
m_age = value
End Set
End Property
Public Property CanCode As Boolean
Get
Return m_canCode
End Get
Set(ByVal value As Boolean)
m_canCode = value
End Set
End Property
End Class

Then VB 9.0 allows us to create and initialize an object of type person with the following syntax:

Dim p As Person = New Person With { _
.Name = "John Doe", _
.Age = 31, _
.CanCode = True _
}

This is a pattern that is semantically equivalent to:

Dim p As Person = New Person
p.Name = "John Doe"
p.Age = 31
p.CanCode = True

You can use the above object initializer in an expression context.  In the following example, the object is initialized, and then passed as an argument to a method:

PrintPerson(New Person With { _
.Name = "John Doe", _
.Age = 31, _
.CanCode = True _
})

Initializing with Constructor Arguments

If there were a constructor defined that took the name as an argument, you could call that constructor in the object initializer, as follows:

PrintPerson(New Person("John Doe") With { _
.Age = 31, _
.CanCode = True _
})

Initializing Embedded Objects

Sometimes an object contains other objects.  This is a very common pattern.

You can initialize the above Rectangle class with its embedded Point objects as follows:

Class Point
Private m_x, m_y As Integer
Public Property X As Integer
Get
Return m_x
End Get
Set(ByVal value As Integer)
m_x = value
End Set
End Property
Public Property Y As Integer
Get
Return m_y
End Get
Set(ByVal value As Integer)
m_y = value
End Set
End Property
End Class

Class Rectangle
Private m_p1 As Point
Private m_p2 As Point
Public Property P1 As Point
Get
Return m_p1
End Get
Set
m_p1 = Value
End Set
End Property
Public Property P2 As Point
Get
Return m_p2
End Get
Set
m_p2 = Value
End Set
End Property
End Class

Module Module1
Sub Main()
Dim r As Rectangle = New Rectangle With { _
.P1 = New Point() With { _
.X = 0, _
.Y = 1 _
}, _
.P2 = New Point() With { _
.X = 2, _
.Y = 3 _
} _
}
End Sub
End Module

Collection Initializer

Using C# 3.0, you can initialize a collection with elements for the newly created collection.  This isn’t a feature of VB 9.0.  However, instead of initializing collections, you can initialize arrays.  For example, you can initialize an array of integers like this:

Dim source() As Integer = {3, 8, 4, 6, 1, 7, 9, 2, 4, 8}

You can initialize an array of objects like this:

Class Point
Private m_x, m_y As Integer
Public Property X As Integer
Get
Return m_x
End Get
Set(ByVal value As Integer)
m_x = value
End Set
End Property
Public Property Y As Integer
Get
Return m_y
End Get
Set(ByVal value As Integer)
m_y = value
End Set
End Property
End Class

Module Module1
Sub Main()
Dim source As Point() = { _
new Point() With { .X = 1, .Y = 2 }, _
new Point() With { .X = 3, .Y = 4 } _
}
For Each i In source
Console.WriteLine(i.X)
Next
End Sub
End Module

[Table of Contents] [Next Topic] [Blog Map]