Blog Map
[Table of Contents] [Next Topic] [Blog Map] This blog is inactive. New blog: EricWhite.com/blog
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.
It is very convenient and much more readable to create object collections/graphs/trees using object initializers.
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.
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 PropertyEnd 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 PropertyEnd Class
You would typically create an object graph as follows:
Dim r As Rectangle = New Rectangler.P1 = New Pointr.P1.X = 1r.P1.Y = 2r.P2 = New Pointr.P2.X = 3r.P2.Y = 4
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.
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 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 PropertyEnd 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 Personp.Name = "John Doe"p.Age = 31p.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 _ })
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 _})
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 PropertyEnd 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 PropertyEnd 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 SubEnd Module
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 PropertyEnd 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 SubEnd Module
[Table of Contents] [Next Topic] [Blog Map]