Partager via


Using Nominal Types for Tuples - VB

[Table of Contents] [Next Topic]

The following example (from the previous topic on anonymous types) shows projection of a collection of anonymous types:

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

Blog TOC

Dim custList() As Customer = { _
New Customer With { _
.Name = "Bob", _
.Address = "123 Main Street, Seattle, WA 98111", _
.Phone = "555-1234" _
}, _
New Customer With { _
.Name = "Bill", _
.Address = "555 Center Street, Tacoma, WA 97158", _
.Phone = "555-9999" _
} _
}
Dim newCustList = _
custList.Select( _
Function(c) New With { _
.UCName = c.Name.ToUpper, _
.UCAddress = c.Address.ToUpper _
} _
)
For Each c In newCustList
Console.WriteLine(c.UCName)
Next

However, one problem with this code is that as written, we can't move the query into its own method.

A different approach, which I like more, is to define a named type for the tuple.  In C#, a convenient syntax is the automatic properties syntax, which allows you to define a type in a very few lines.  VB doesn’t have an equivalent feature.  However, you can gain the same expressiveness and succinctness by using public fields.  If you are using these types only for tuples, and only within a limited scope, I don’t have a problem with this approach.  Using this approach, you can define a class with n fields in n+2 lines of code.  The syntactic noise is kept to a minimum.  Depending on the circumstances, you can declare the tuple class as a nested class.

One of the characteristics of dynamic languages is the ability to add new properties to a tuple type very easily.  This characteristic is shared by VB when projecting using anonymous types.  However, I find that I have the same type of experience when using named types in the fashion described in this topic.  I don't find it particularly onerous to add new fields to the tuple type.  I have a little macro that creates one for me, and all I need to type are the type and the name.  The malleability of tuple types is nearly as good as when using a dynamic type, except that you get strong typing, and a good Intellisense experience in VS.

Consider the following code, where the tuple is defined using a private named class, and the query and projection are refactored into a separate method.

Public Class Customer
Private m_name As String
Private m_address As String
Private m_phone As String
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 Address() As String
Get
Return m_address
End Get
Set(ByVal value As String)
m_address = value
End Set
End Property
Public Property Phone() As String
Get
Return m_phone
End Get
Set(ByVal value As String)
m_phone = value
End Set
End Property
End Class

Module Module1
Private Class UCCustomer
Public UCName As String
Public UCAddress As String
Public Phone As String
End Class

Private Function ProjectUC(ByVal source As IEnumerable(Of Customer)) As IEnumerable(Of UCCustomer)
Return source.Select(Function(c) New UCCustomer With { _
.UCName = c.Name.ToUpper, _
.UCAddress = c.Address.ToUpper _
})
End Function

Sub Main()
Dim custList() As Customer = { _
New Customer With { _
.Name = "Bob", _
.Address = "123 Main Street, Seattle, WA 98111", _
.Phone = "555-1234" _
}, _
New Customer With { _
.Name = "Bill", _
.Address = "555 Center Street, Tacoma, WA 97158", _
.Phone = "555-9999" _
} _
}
Dim newCustList = ProjectUC(custList)
For Each c In newCustList
Console.WriteLine(c.UCName)
Next
End Sub
End Module

Notice in the above code that the object initializer for the tuple type is nearly identical to the object initializer when projecting an anonymous type.  The only difference is the naming of the type in the initializer.

When writing queries on the fly, anonymous types are handy.

Sometimes I'll expose the nominal tuple type as a public class, and it becomes part of the programming interface to the classes and methods that contain my FP code.  For an example of this approach (in C#), see Open XML SDK and LINQ to XML.

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

Examples.txt

Comments

  • Anonymous
    December 16, 2008
    Of course, with VB10, you will be able to define full-blown properties with single lines instead of needing to use public fields.