<p>I'm trying to serialize a Type object in the following way:</p>

<pre><code>Type myType = typeof (StringBuilder);
var serializer = new XmlSerializer(typeof(Type));
TextWriter writer = new StringWriter();
serializer.Serialize(writer, myType);
</code></pre>

<p>When I do this, the call to Serialize throws the following exception:  </p>

<blockquote>
  <p>"The type System.Text.StringBuilder was not expected. Use the
  XmlInclude or SoapInclude attribute to specify types that are not
  known statically."</p>
</blockquote>

<p>Is there a way for me to serialize the <code>Type</code> object?  Note that I am not trying to serialize the <code>StringBuilder</code> itself, but the <code>Type</code> object containing the metadata about the <code>StringBuilder</code> class.</p>

[{'answer_id': 12314, 'author': 'AdamSane', 'author_id': 805, 'author_profile': 'https://Stackoverflow.com/users/805', 'pm_score': 1, 'selected': False, 'text': '<p>Just looked at its definition, it is not marked as Serializable. If you really need this data to be serialize, then you may have to convert it to a custom class that is marked as such.</p>\n\n<pre><code>public abstract class Type : System.Reflection.MemberInfo\n    Member of System\n\nSummary:\nRepresents type declarations: class types, interface types, array types, value types, enumeration types, type parameters, generic type definitions, and open or closed constructed generic types.\n\nAttributes:\n[System.Runtime.InteropServices.ClassInterfaceAttribute(0),\nSystem.Runtime.InteropServices.ComDefaultInterfaceAttribute(System.Runtime.InteropServices._Type),\nSystem.Runtime.InteropServices.ComVisibleAttribute(true)]\n</code></pre>\n'}, {'answer_id': 12315, 'author': 'rjzii', 'author_id': 1185, 'author_profile': 'https://Stackoverflow.com/users/1185', 'pm_score': 2, 'selected': False, 'text': '<p>According to the MSDN documentation of System.Type [1] you should be able to serialize the System.Type object. However, as the error is explicitly referring to System.Text.StringBuilder, that is likely the class that is causing the serialization error.</p>\n\n<p>[1] Type Class (System) - <a href="http://msdn.microsoft.com/en-us/library/system.type.aspx" rel="nofollow noreferrer">http://msdn.microsoft.com/en-us/library/system.type.aspx</a></p>\n'}, {'answer_id': 12342, 'author': 'Brian Sullivan', 'author_id': 767, 'author_profile': 'https://Stackoverflow.com/users/767', 'pm_score': 8, 'selected': True, 'text': "<p>I wasn't aware that a Type object could be created with only a string containing the fully-qualified name.  To get the fully qualified name, you can use the following:</p>\n\n<pre><code>string typeName = typeof (StringBuilder).FullName;\n</code></pre>\n\n<p>You can then persist this string however needed, then reconstruct the type like this:</p>\n\n<pre><code>Type t = Type.GetType(typeName);\n</code></pre>\n\n<p>If you need to create an instance of the type, you can do this:</p>\n\n<pre><code>object o = Activator.CreateInstance(t);\n</code></pre>\n\n<p>If you check the value of o.GetType(), it will be StringBuilder, just as you would expect.</p>\n"}, {'answer_id': 9809872, 'author': 'hypehuman', 'author_id': 1269598, 'author_profile': 'https://Stackoverflow.com/users/1269598', 'pm_score': 4, 'selected': False, 'text': "<p>I had the same problem, and my solution was to create a SerializableType class.  It freely converts to and from System.Type, but it serializes as a string.  All you have to do is declare the variable as a SerializableType, and from then on you can refer to it as System.Type.</p>\n\n<p>Here is the class:</p>\n\n<pre><code>// a version of System.Type that can be serialized\n[DataContract]\npublic class SerializableType\n{\n    public Type type;\n\n    // when serializing, store as a string\n    [DataMember]\n    string TypeString\n    {\n        get\n        {\n            if (type == null)\n                return null;\n            return type.FullName;\n        }\n        set\n        {\n            if (value == null)\n                type = null;\n            else\n            {\n                type = Type.GetType(value);\n            }\n        }\n    }\n\n    // constructors\n    public SerializableType()\n    {\n        type = null;\n    }\n    public SerializableType(Type t)\n    {\n        type = t;\n    }\n\n    // allow SerializableType to implicitly be converted to and from System.Type\n    static public implicit operator Type(SerializableType stype)\n    {\n        return stype.type;\n    }\n    static public implicit operator SerializableType(Type t)\n    {\n        return new SerializableType(t);\n    }\n\n    // overload the == and != operators\n    public static bool operator ==(SerializableType a, SerializableType b)\n    {\n        // If both are null, or both are same instance, return true.\n        if (System.Object.ReferenceEquals(a, b))\n        {\n            return true;\n        }\n\n        // If one is null, but not both, return false.\n        if (((object)a == null) || ((object)b == null))\n        {\n            return false;\n        }\n\n        // Return true if the fields match:\n        return a.type == b.type;\n    }\n    public static bool operator !=(SerializableType a, SerializableType b)\n    {\n        return !(a == b);\n    }\n    // we don't need to overload operators between SerializableType and System.Type because we already enabled them to implicitly convert\n\n    public override int GetHashCode()\n    {\n        return type.GetHashCode();\n    }\n\n    // overload the .Equals method\n    public override bool Equals(System.Object obj)\n    {\n        // If parameter is null return false.\n        if (obj == null)\n        {\n            return false;\n        }\n\n        // If parameter cannot be cast to SerializableType return false.\n        SerializableType p = obj as SerializableType;\n        if ((System.Object)p == null)\n        {\n            return false;\n        }\n\n        // Return true if the fields match:\n        return (type == p.type);\n    }\n    public bool Equals(SerializableType p)\n    {\n        // If parameter is null return false:\n        if ((object)p == null)\n        {\n            return false;\n        }\n\n        // Return true if the fields match:\n        return (type == p.type);\n    }\n}\n</code></pre>\n\n<p>and an example of usage:</p>\n\n<pre><code>[DataContract]\npublic class A\n{\n\n    ...\n\n    [DataMember]\n    private Dictionary&lt;SerializableType, B&gt; _bees;\n\n    ...\n\n    public B GetB(Type type)\n    {\n        return _bees[type];\n    }\n\n    ...\n\n}\n</code></pre>\n\n<p>You might also consider using AssemblyQualifiedName instead of Type.FullName - see comment by @GreyCloud</p>\n"}, {'answer_id': 21435254, 'author': 'Dzyann', 'author_id': 752842, 'author_profile': 'https://Stackoverflow.com/users/752842', 'pm_score': 3, 'selected': False, 'text': '<p><a href="https://stackoverflow.com/a/12342/752842">Brian\'s</a> answer works well if the type is in the same assembly as the call (like GreyCloud pointed out in one of the comments).\nSo if the type is in another assembly you need to use the <a href="http://msdn.microsoft.com/en-us/library/system.type.assemblyqualifiedname%28v=vs.110%29.aspx" rel="noreferrer">AssemblyQualifiedName</a> as GreyCloud also pointed out.</p>\n\n<p>However as the <a href="http://msdn.microsoft.com/en-us/library/system.type.assemblyqualifiedname%28v=vs.110%29.aspx" rel="noreferrer">AssemblyQualifiedName</a> saves the version, if your assemblies have a different version than the one in the string where you have the type, it won\'t work.</p>\n\n<p>In my case this was an issue and I solved it like this:</p>\n\n<pre><code>string typeName = typeof (MyClass).FullName;\n\nType type = GetTypeFrom(typeName);\n\nobject myInstance = Activator.CreateInstance(type);\n</code></pre>\n\n<p><strong>GetTypeFrom Method</strong></p>\n\n<pre><code>private Type GetTypeFrom(string valueType)\n    {\n        var type = Type.GetType(valueType);\n        if (type != null)\n            return type;\n\n        try\n        {\n            var assemblies = AppDomain.CurrentDomain.GetAssemblies();                \n\n            //To speed things up, we check first in the already loaded assemblies.\n            foreach (var assembly in assemblies)\n            {\n                type = assembly.GetType(valueType);\n                if (type != null)\n                    break;\n            }\n            if (type != null)\n                return type;\n\n            var loadedAssemblies = assemblies.ToList();\n\n            foreach (var loadedAssembly in assemblies)\n            {\n                foreach (AssemblyName referencedAssemblyName in loadedAssembly.GetReferencedAssemblies())\n                {\n                    var found = loadedAssemblies.All(x =&gt; x.GetName() != referencedAssemblyName);\n\n                    if (!found)\n                    {\n                        try\n                        {\n                            var referencedAssembly = Assembly.Load(referencedAssemblyName);\n                            type = referencedAssembly.GetType(valueType);\n                            if (type != null)\n                                break;\n                            loadedAssemblies.Add(referencedAssembly);\n                        }\n                        catch\n                        {\n                            //We will ignore this, because the Type might still be in one of the other Assemblies.\n                        }\n                    }\n                }\n            }                \n        }\n        catch(Exception exception)\n        {\n            //throw my custom exception    \n        }\n\n        if (type == null)\n        {\n            //throw my custom exception.\n        }\n\n        return type;\n    }\n</code></pre>\n\n<p>I am posting this in case anyone needs it.</p>\n'}, {'answer_id': 54830442, 'author': 'Peter Riesz', 'author_id': 1003150, 'author_profile': 'https://Stackoverflow.com/users/1003150', 'pm_score': 2, 'selected': False, 'text': '<p>I came across this issue trying to do binary serialization in .net standard 2.0.  I ended up solving the problem using a custom <code>SurrogateSelector</code> and <code>SerializationBinder</code>.</p>\n\n<p>The <code>TypeSerializationBinder</code> was required because the framework was having trouble resolving <code>System.RuntimeType</code> before it got <code>SurrogateSelector</code>.  I don\'t really understand why the type must be resolved before this step though...</p>\n\n<p>Here is the code:</p>\n\n<pre><code>// Serializes and deserializes System.Type\npublic class TypeSerializationSurrogate : ISerializationSurrogate {\n    public void GetObjectData(object obj, SerializationInfo info, StreamingContext context) {\n        info.AddValue(nameof(Type.FullName), (obj as Type).FullName);\n    }\n\n    public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector) {\n        return Type.GetType(info.GetString(nameof(Type.FullName)));\n    }\n}\n\n// Just a stub, doesn\'t need an implementation\npublic class TypeStub : Type { ... }\n\n// Binds "System.RuntimeType" to our TypeStub\npublic class TypeSerializationBinder : SerializationBinder {\n    public override Type BindToType(string assemblyName, string typeName) {\n        if(typeName == "System.RuntimeType") {\n            return typeof(TypeStub);\n        }\n        return Type.GetType($"{typeName}, {assemblyName}");\n    }\n}\n\n// Selected out TypeSerializationSurrogate when [de]serializing Type\npublic class TypeSurrogateSelector : ISurrogateSelector {\n    public virtual void ChainSelector(ISurrogateSelector selector) =&gt; throw new NotSupportedException();\n\n    public virtual ISurrogateSelector GetNextSelector() =&gt; throw new NotSupportedException();\n\n    public virtual ISerializationSurrogate GetSurrogate(Type type, StreamingContext context, out ISurrogateSelector selector) {\n        if(typeof(Type).IsAssignableFrom(type)) {\n            selector = this;\n            return new TypeSerializationSurrogate();\n        }\n        selector = null;\n        return null;\n    }\n}\n</code></pre>\n\n<p>Usage Example:</p>\n\n<pre><code>byte[] bytes\nvar serializeFormatter = new BinaryFormatter() {\n    SurrogateSelector = new TypeSurrogateSelector()\n}\nusing (var stream = new MemoryStream()) {\n    serializeFormatter.Serialize(stream, typeof(string));\n    bytes = stream.ToArray();\n}\n\nvar deserializeFormatter = new BinaryFormatter() {\n    SurrogateSelector = new TypeSurrogateSelector(),\n    Binder = new TypeDeserializationBinder()\n}\nusing (var stream = new MemoryStream(bytes)) {\n    type = (Type)deserializeFormatter .Deserialize(stream);\n    Assert.Equal(typeof(string), type);\n}\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/12306', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/767/']