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
zipCode
property in the "new"Address
class is of typeString
while thezip
property in the "old"LegacyAddress
class is of typeInteger?
. - Where the
Customer
class has a name broken into component parts (firstName
,middleName
,lastName
,businessName
), theLegacyCustomer
class has all the parts combined into a singlename
property. - The
LegacyCustomer
class has atype
andsubtype
property while these properties do not exist in theCustomer
class. - The
customerID
property of theCustomer
class will almost certainly be different than theid
property of theLegacyCustomer
class.
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
CType
operation 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
Narrowing
operator and not theWidening
?