Search code examples
.netvb.netobjectcomclone

Duplicating a Non-Serializable (COM) Object


I'm using VB.Net 2010. I want to duplicate the contents of a (COM) object entered to my application by an external (off-the-self) application. I wouldn't like to copy field & property values one by one (as fields/properties may be added or removed on future application builds).

Object type is non-serializable.

I've tried Reflection as follows (VB code suggested on thread copy one object to another):

Imports System.Reflection

Public Class ObjectHelper

    ' Creates a copy of an object
    Public Shared Function GetCopy(Of SourceType As {Class, New})(ByVal Source As SourceType) As SourceType

        Dim ReturnValue As New SourceType
        Dim sourceProperties() As PropertyInfo = Source.GetType().GetProperties()

        For Each sourceProp As PropertyInfo In sourceProperties
            sourceProp.SetValue(
                ReturnValue, 
                sourceProp.GetValue(Source, Nothing),
                Nothing)
        Next

        Return ReturnValue

    End Function

End Class

That does not work, as the returned sourceProperties() array is empty.

Any Ideas?


Solution

  • First there is a bug in the implementation

    Dim sourceProperties() As PropertyInfo = Source.GetType().GetProperties()
    

    should be

    Dim sourceProperties() As PropertyInfo = GetType(SourceType).GetProperties()
    

    Source.GetType() returns _COMObject type as that is the real type of your object, while you really want to check your interface type which is implemented by the object.

    Other solution is to check whether the object implements any of IPersist interfaces and use that for real COM serialization. You can do that by casting the object to e.g. System.Runtime.InteropServices.ComTypes.IPersistFile. Unfortunately, other IPersist* interfaces are not defined in that namespace so you will have to import them from somewhere.