using System.Collections.Generic;
using System.Xml.Serialization;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO.Compression;
public const string RootElementName = "Project";
public const string RootElementNamespaceURI = "https://stackoverflow.com/questions/49977144";
public string BaseProperty { get; set; }
public class ProjectCustomerA : Project
public string CustomerProperty { get; set; }
public string ProjectCustomerAProperty { get; set; }
public class ProjectCustomerB : Project
public string CustomerProperty { get; set; }
public string ProjectCustomerBProperty { get; set; }
public static partial class XmlSerializationHelper
public static T LoadFromXmlAsType<T>(this string xmlString)
return new StringReader(xmlString).LoadFromXmlAsType<T>();
public static T LoadFromXmlAsType<T>(this TextReader textReader)
using (var xmlReader = XmlReader.Create(textReader, new XmlReaderSettings { CloseInput = false }))
return xmlReader.LoadFromXmlAsType<T>();
public static T LoadFromXmlAsType<T>(this XmlReader xmlReader)
while (xmlReader.NodeType != XmlNodeType.Element)
throw new XmlException("No root element");
var serializer = XmlSerializerFactory.Create(typeof(T), xmlReader.LocalName, xmlReader.NamespaceURI);
return (T)serializer.Deserialize(xmlReader);
public static string SaveToXmlAsType<T>(this T obj, string localName, string namespaceURI)
var sb = new StringBuilder();
using (var writer = new StringWriter(sb))
obj.SaveToXmlAsType(writer, localName, namespaceURI);
public static void SaveToXmlAsType<T>(this T obj, TextWriter textWriter, string localName, string namespaceURI)
using (var xmlWriter = XmlWriter.Create(textWriter, new XmlWriterSettings { CloseOutput = false, Indent = true }))
obj.SaveToXmlAsType(xmlWriter, localName, namespaceURI);
public static void SaveToXmlAsType<T>(this T obj, XmlWriter xmlWriter, string localName, string namespaceURI)
var serializer = XmlSerializerFactory.Create(obj.GetType(), localName, namespaceURI);
serializer.Serialize(xmlWriter, obj);
public static class XmlSerializerFactory
readonly static Dictionary<Tuple<Type, string, string>, XmlSerializer> cache;
readonly static object padlock;
static XmlSerializerFactory()
cache = new Dictionary<Tuple<Type, string, string>, XmlSerializer>();
public static XmlSerializer Create(Type serializedType, string rootName, string rootNamespace)
if (serializedType == null)
throw new ArgumentNullException();
if (rootName == null && rootNamespace == null)
return new XmlSerializer(serializedType);
XmlSerializer serializer;
var key = Tuple.Create(serializedType, rootName, rootNamespace);
if (!cache.TryGetValue(key, out serializer))
cache[key] = serializer = new XmlSerializer(serializedType, new XmlRootAttribute { ElementName = rootName, Namespace = rootNamespace });
public static void Test()
var roota = new ProjectCustomerA
BaseProperty = "base property value",
CustomerProperty = "shared property value",
ProjectCustomerAProperty = "project A value",
var xmla = roota.SaveToXmlAsType(Project.RootElementName, Project.RootElementNamespaceURI);
var rootb = xmla.LoadFromXmlAsType<ProjectCustomerB>();
var xmlb = rootb.SaveToXmlAsType(Project.RootElementName, Project.RootElementNamespaceURI);
Assert.IsTrue(roota.BaseProperty == rootb.BaseProperty);
Assert.IsTrue(roota.CustomerProperty == rootb.CustomerProperty);
Console.WriteLine("\nXML for {0}:", roota);
Console.WriteLine("\nDeserialized and re-serialized XML for {0}:", rootb);
public class AssertionFailedException : System.Exception
public AssertionFailedException() : base() { }
public AssertionFailedException(string s) : base(s) { }
public static class Assert
public static void IsTrue(bool value)
public static void IsTrue(bool value, string message)
throw new AssertionFailedException(message ?? "failed");
public static void Main()
Console.WriteLine("Roslyn 2.0 Compiler; Environment version: " + Environment.Version);
Console.WriteLine("Uncaught exception: ");