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?