On numerous occasions I’ve been involved in projects, where I’ve had an instance of a given object type present in one namespace and the need to convert it to an object type with exactly the same signature, but in another namespace.

Usually, in a scenarios of dealing with web services – where different web services, logically refer to the same types, but the proxy classes are generated in different namespaces – making the incompatible.

The non-technical approach, would be to convert the instance types with helper methods. Copying each data field/property one-by-one. For large and deeply nested structures, this quickly becomes a dead end.

To solve this problem, I use the less-known serialization trick:

Serialize the source instance
Deserialize the source instance, but to the destination instance type
This of course requires the types to be serializable, if you’re dealing with web service proxies – this is not an issue – as these will most probably already be serializable 🙂

The C# code for doing the conversion:

 

        /// 
<summary>
        /// Converts a given instance (of a given type) to the same type, but present in another namespace
        /// (requires types to be serializable).
        /// </summary>

        /// <typeparam name="T">The type to convert to</typeparam>
        /// <param name="instance">The instance containing the source type</param>
        /// <returns>The covnerted type</returns>
        private static T ConvertType<T>(object instance)
        {
            if (instance == null)
            {
                throw new ArgumentNullException("instance");
            }

            var typeSource = instance.GetType();
            var typeDestination = typeof(T);

            T result = default(T);

            // We're using a Memorystream for the serialization magic
            using (var ms = new MemoryStream())
            {
                //  Create the serializer for the incoming type
                var serializer = new XmlSerializer(typeSource);

                //  Create a XML text writer, and serialize the incomming instance to memory
                var tw = new XmlTextWriter(ms, Encoding.UTF8);
                serializer.Serialize(tw, instance);

                //  Rewind the MemoryStream to the beginning.
                ms.Position = 0;

                //  Now, create the deserializer for the destination type
                var deserializer = new XmlSerializer(typeDestination);

                using (var reader = new XmlTextReader(ms))
                {
                    try
                    {
                        result = (T)deserializer.Deserialize(reader);
                    }
                    catch (Exception ex)
                    {
                        throw new ApplicationException(String.Format("Converting from type: {0}->{1} failed", typeSource.FullName, typeDestination.FullName), ex);
                    }
                }
            }

            return result;
        }

Example:

            namespace OneNamespace
            {
                [Serializable]
                public class Person
                {
                    public string Name;
                    public int Age;
                }
            }

            namespace OtherNamespace
            {
                [Serializable]
                public class Person
                {
                    public string Name;
                    public int Age;
                }
            }


            var person1 = new OneNamespace.Person() {Name = "Henrik", Age = 25};

            // Obviously, casting is NOT an option :-)
            //OtherNamespace.Person person2 = (OtherNamespace.Person)person1;

            var person2 = ConvertType<OtherNamespace.Person>(person1);