I've been trying to read up on possible methods of casting one of my class objects to another to "simplify" some of my programming going forward. Specifically, I have a class I've built for some new development to store and retrieve information to/from our database, but I have a "legacy" class that I still need to use to retrieve data from an older iteration of the database until all of the data has been migrated and none of the applications/systems are looking for information in that older database. Here's an example:
Public Class Customer
Public Property customerID As Integer
Public Property firstName As String
Public Property middleName As String
Public Property lastName As String
Public Property businessName As String
Public Property mailingAddress As Address
Public Property homePhone As String
Public Property workPhone As String
End Class
Public Class Address
Public Property address1 As String
Public Property address2 As String
Public Property address3 As String
Public Property city As String
Public Property state As String
Public Property zipCode As String
Public Property zip4 As String
End Class
And the old class objects:
Public Class LegacyCustomer
Public Property id As Int64 = -1
Public Property type As String = String.Empty
Public Property name As String = String.Empty
Public Property subtype As Integer? = Nothing
End Class
Public Class LegacyAddress
Public Property id As Int64
Public Property type As String = String.Empty
Public Property addr1 As String = String.Empty
Public Property addr2 As String = String.Empty
Public Property city As String = String.Empty
Public Property state As String = String.Empty
Public Property county As String = String.Empty
Public Property zip As Integer? = Nothing
Public Property zip4 As Integer? = Nothing
End Class
As you can see, there are several similar properties between the old and new objects in just the above example code, but not all of them are able to "match up" exactly with their counterparts. A couple of examples:
- The
zipCodeproperty in the "new"Addressclass is of typeStringwhile thezipproperty in the "old"LegacyAddressclass is of typeInteger?. - Where the
Customerclass has a name broken into component parts (firstName,middleName,lastName,businessName), theLegacyCustomerclass has all the parts combined into a singlenameproperty. - The
LegacyCustomerclass has atypeandsubtypeproperty while these properties do not exist in theCustomerclass. - The
customerIDproperty of theCustomerclass will almost certainly be different than theidproperty of theLegacyCustomerclass.
So, in my research, I've been looking into building a custom type conversion routine a la this answer by Anthony Pegram to the similar question, "cast class into another class or convert class to another" I don't believe it would be too incredibly challenging to use this method, but I wonder if I need to use the Narrowing or a Widening version of this method. I would assume the former, but I'm not certain and would appreciate some guidance.
Also, because the mailingAddress property of the Customer class is of another class type and there is no matching object in the LegacyCustomer class, I'm guessing I would need to possibly create a matching "placeholder" address property (of type LegacyAddress) into the LegacyCustomer object in order for this to work as intended/expected. Here's kinda what I envision (this is all untested "pseudo-code" for now):
Add a property to the LegacyCustomer object
Public Class LegacyCustomer
'properties as defined above, plus
Public Property address As LegacyAddress
End Class
Public Class Customer
'properties as defined above
Public Shared Narrowing Operator CType(ByVal cust As Customer) As LegacyCustomer
Dim result As New LegacyCustomer
With result
If Not cust.businessName Is Nothing AndAlso Not String.IsNullOrEmpty(cust.businessName) Then
.name = cust.businessName
Else
If Not cust.lastName Is Nothing AndAlso Not String.IsNullOrEmpty(cust.lastName) Then
.name = cust.lastName & "," & cust.firstName & " " & cust.middleName
Else
.name = cust.firstName & " " & cust.middleName
End If
End If
.name = .name.Trim()
.type = "F"
With .address
.address1 = cust.mailingAddress.address1
.address2 = cust.mailingAddress.address2
If Not cust.mailingAddress.address3 Is Nothing AndAlso Not String.IsNullOrEmpty(cust.mailingAddress.address3) Then
.address2 = cust.mailingAddress.address2 & " " & cust.mailingAddress.address3
End If
.city = cust.mailingAddress.city
.state = cust.mailingAddress.state
If IsNumeric(cust.mailingAddress.zipCode) Then
.zip = TryCast(cust.mailingAddress.zipCode, Integer)
End If
If IsNumeric(cust.mailingAddress.zip4) Then
.zip4 = TryCast(cust.mailingAddress.zip4, Integer)
End If
.type = "A"
End With
End With
Return result
End Operator
End Class
Then, I'd probably have something similar in the LegacyCustomer class to convert it back the other way, although that may be a bit trickier.
I guess my actual question is in two parts:
- Is overriding the
CTypeoperation in this way the "most effective" method of converting these objects from one to another? and - Am I correct in assuming that I'll need to use the
Narrowingoperator and not theWidening?