I understood that anonymous types are marked private by the compiler and the properties are read-only. Is there a way to serialize them to xml (without deserialize) ? It works with JSON, how can I do it with XML?
9 Answers
Something like this should get you started...
class Program
{
static void Main(string[] args)
{
var me = new
{
Hello = "World",
Other = new
{
My = "Object",
V = 1,
B = (byte)2
}
};
var x = me.ToXml();
}
}
public static class Tools
{
private static readonly Type[] WriteTypes = new[] {
typeof(string), typeof(DateTime), typeof(Enum),
typeof(decimal), typeof(Guid),
};
public static bool IsSimpleType(this Type type)
{
return type.IsPrimitive || WriteTypes.Contains(type);
}
public static XElement ToXml(this object input)
{
return input.ToXml(null);
}
public static XElement ToXml(this object input, string element)
{
if (input == null)
return null;
if (string.IsNullOrEmpty(element))
element = "object";
element = XmlConvert.EncodeName(element);
var ret = new XElement(element);
if (input != null)
{
var type = input.GetType();
var props = type.GetProperties();
var elements = from prop in props
let name = XmlConvert.EncodeName(prop.Name)
let val = prop.GetValue(input, null)
let value = prop.PropertyType.IsSimpleType()
? new XElement(name, val)
: val.ToXml(name)
where value != null
select value;
ret.Add(elements);
}
return ret;
}
}
... resulting xml ...
<object>
<Hello>World</Hello>
<Other>
<My>Object</My>
<V>1</V>
<B>2</B>
</Other>
</object>

- 22,160
- 4
- 52
- 69
-
I guess `Type.IsValueType` could be a nice shortcut for most of the `IsAssignableFrom` s. Doesn't catch the `string` though. – sunside Aug 16 '10 at 15:55
-
`IsValueType` can be a wrong choice. This would use the ToString value to convert the type. But I have made a change that should be much easier to understand. – Matthew Whited Aug 16 '10 at 17:26
-
3Hey - your code works like a charm. I made some minor changes, so that it supports Arrays, I wrote about it here: http://martinnormark.com/serialize-c-dynamic-and-anonymous-types-to-xml – MartinHN Feb 05 '11 at 08:31
-
OK, this is a good sample... now, how can I serialize objects, that *contains* anonymous types... i suppose via custom serialization... – serhio Oct 06 '11 at 15:03
-
This may not be useful to many people, but is the right answer to this particular question – nik.shornikov Sep 26 '13 at 18:16
-
Here's a blog post that was probably inspired by this answer: http://martinnormark.com/serialize-c-dynamic-and-anonymous-types-to-xml/ – Cristian Diaconescu Mar 14 '14 at 08:48
It can't be accomplished using XmlSerializer
nor DataContractSerializer
. It can be done by a manually written code, as demonstrated below (I can't comment as to whether the code is comprehensive enough to handle all types - but it's a very good start).

- 17,068
- 9
- 59
- 93

- 160,644
- 26
- 247
- 397
-
4That doesn't mean you can't do it with a third-party class, though. – Matthew Flaschen Mar 08 '10 at 21:23
-
-
@Radu: I don't know what you mean "write something generic". Not if you're talking about using the XML Serializer. The answer from "Matthew Whited" shows you how to do this without using the XML Serializer. – John Saunders Mar 08 '10 at 21:50
-
It's probably one of the guys that downvotes all answers that don't get marked as the "correct" answer. Shame that people can't see that you are also correct in that the built-in xml serializer will not work. – Matthew Whited Mar 09 '10 at 04:38
-
3I do believe that Matthews answer below is the correct answer. I took his code and it worked out of the box - I made some changes to make it support Arrays: http://martinnormark.com/serialize-c-dynamic-and-anonymous-types-to-xml – MartinHN Feb 05 '11 at 08:32
-
-
@GeorgeMauer: what sort of issue? This is how the XML Serializer has behaved since day one. – John Saunders Aug 31 '14 at 18:33
-
Yeah, but it still isn't a good idea for webapi to randomly throw errors by default when doing a thing that it would be perfectly reasonable to expect would work. [I couldn't find any feature requests so I created one](https://aspnetwebstack.codeplex.com/workitem/2123) – George Mauer Aug 31 '14 at 18:36
-
@GeorgeMauer: what's this have to do with web api? I don't think it even existed when this question was asked. Are you replying to the correct question? – John Saunders Aug 31 '14 at 18:39
-
I see, yeah, my context doesn't really apply here. It *would* be nice to create an issue to fix this behavior in XmlSerializer directly. I have no idea where that issue tracker would even be though. Perhaps the visual studio uservoice? They seem to at least track c# feature requests. – George Mauer Sep 01 '14 at 16:06
-
@GeorgeMauer: the XML Serializer is no longer maintained, so there would be no issue tracker for that. – John Saunders Sep 01 '14 at 19:27
Thank you, excellent work @Matthew and @Martin.
I have made a couple of modification to accomodate Nullables and Enums. Also I have changed it so that array elements are named according to the name of the property + index.
Here is the code if anyone is interested
public static class ObjectExtensions {
#region Private Fields
private static readonly Type[] WriteTypes = new[] {
typeof(string), typeof(DateTime), typeof(Enum),
typeof(decimal), typeof(Guid),
};
#endregion Private Fields
#region .ToXml
/// <summary>
/// Converts an anonymous type to an XElement.
/// </summary>
/// <param name="input">The input.</param>
/// <returns>Returns the object as it's XML representation in an XElement.</returns>
public static XElement ToXml(this object input) {
return input.ToXml(null);
}
/// <summary>
/// Converts an anonymous type to an XElement.
/// </summary>
/// <param name="input">The input.</param>
/// <param name="element">The element name.</param>
/// <returns>Returns the object as it's XML representation in an XElement.</returns>
public static XElement ToXml(this object input, string element) {
return _ToXml(input, element);
}
private static XElement _ToXml(object input, string element, int? arrayIndex = null, string arrayName = null) {
if (input == null)
return null;
if (String.IsNullOrEmpty(element)) {
string name = input.GetType().Name;
element = name.Contains("AnonymousType")
? "Object"
: arrayIndex != null
? arrayName + "_" + arrayIndex
: name;
}
element = XmlConvert.EncodeName(element);
var ret = new XElement(element);
if (input != null) {
var type = input.GetType();
var props = type.GetProperties();
var elements = props.Select(p => {
var pType = Nullable.GetUnderlyingType(p.PropertyType) ?? p.PropertyType;
var name = XmlConvert.EncodeName(p.Name);
var val = pType.IsArray ? "array" : p.GetValue(input, null);
var value = pType.IsArray
? GetArrayElement(p, (Array)p.GetValue(input, null))
: pType.IsSimpleType() || pType.IsEnum
? new XElement(name, val)
: val.ToXml(name);
return value;
})
.Where(v=>v !=null);
ret.Add(elements);
}
return ret;
}
#region helpers
/// <summary>
/// Gets the array element.
/// </summary>
/// <param name="info">The property info.</param>
/// <param name="input">The input object.</param>
/// <returns>Returns an XElement with the array collection as child elements.</returns>
private static XElement GetArrayElement(PropertyInfo info, Array input) {
var name = XmlConvert.EncodeName(info.Name);
XElement rootElement = new XElement(name);
var arrayCount = input == null ? 0 : input.GetLength(0);
for (int i = 0; i < arrayCount; i++) {
var val = input.GetValue(i);
XElement childElement = val.GetType().IsSimpleType() ? new XElement(name + "_" + i, val) : _ToXml(val, null, i, name);
rootElement.Add(childElement);
}
return rootElement;
}
#region .IsSimpleType
public static bool IsSimpleType(this Type type) {
return type.IsPrimitive || WriteTypes.Contains(type);
}
#endregion .IsSimpleType
#endregion helpers
#endregion .ToXml
}

- 1,452
- 1
- 22
- 24
-
This is a nice code (+1 already), but it doesn't handle Lists (List have to be converted to Arrays, .ToArray(), that's not always possible). – rufo May 28 '13 at 23:11
I know this is an old post, but my solution converts an anonymous type to XML in only 2 lines of code.
First convert you anonymous type to JSON, and then from JSON to XML.
var jsonText = JsonConvert.SerializeObject(data); // convert to JSON
XmlDocument doc = JsonConvert.DeserializeXmlNode(jsonText); // convert JSON to XML Document
Sample
var data = new // data - Anonymous Type
{
Request = new
{
OrderNumber = 123,
Note = "Hello World"
}
};
var jsonText = JsonConvert.SerializeObject(data);
XmlDocument doc = JsonConvert.DeserializeXmlNode(jsonText);
Console.WriteLine(doc.OuterXml);
Output
<Request>
<OrderNumber>123</OrderNumber>
<Note>Hello World</Note>
</Request>

- 704
- 11
- 25
-
I was looking exactly for something about that. There is an overhead to pay but it's the simplest solution so far. +1 – T-moty Dec 30 '19 at 16:55
-
that works only if you have single node. to make it generic you can change to ```var jsonText = JsonConvert.SerializeObject(new { AAA = data} ); return JsonConvert.DeserializeXmlNode(jsonText).DocumentElement.InnerXml;``` – Sasha Bond May 12 '23 at 16:13
My own version of then excellent work @Matthew and @Martin : Arrays of enums are now supported and the notion of arrays in generalized into IEnumerable in order to also support all sort of collections.
public static class ObjectExtensions {
/// <summary>
/// Converts an anonymous type to an XElement.
/// </summary>
/// <param name="input">The input.</param>
/// <returns>Returns the object as it's XML representation in an XElement.</returns>
public static XElement ToXml2(this object input) {
return input.ToXml2(null);
}
/// <summary>
/// Converts an anonymous type to an XElement.
/// </summary>
/// <param name="input">The input.</param>
/// <param name="element">The element name.</param>
/// <returns>Returns the object as it's XML representation in an XElement.</returns>
public static XElement ToXml2(this object input, string element) {
return _ToXml(input, element);
}
private static XElement _ToXml(object input, string element, int? arrayIndex = null, string arrayName = null) {
if (input == null)
return null;
if (String.IsNullOrEmpty(element)) {
string name = input.GetType().Name;
element = name.Contains("AnonymousType")
? "Object"
: arrayIndex != null
? arrayName + "_" + arrayIndex
: name;
}
element = XmlConvert.EncodeName(element);
var ret = new XElement(element);
if (input != null) {
var type = input.GetType();
var props = type.GetProperties();
var elements = props.Select(p => {
var pType = Nullable.GetUnderlyingType(p.PropertyType) ?? p.PropertyType;
var name = XmlConvert.EncodeName(p.Name);
var val = pType.IsArray ? "array" : p.GetValue(input, null);
var value = pType.IsEnumerable()
? GetEnumerableElements(p, (IEnumerable)p.GetValue(input, null))
: pType.IsSimpleType2() || pType.IsEnum
? new XElement(name, val)
: val.ToXml2(name);
return value;
})
.Where(v=>v !=null);
ret.Add(elements);
}
return ret;
}
#region helpers
private static XElement GetEnumerableElements(PropertyInfo info, IEnumerable input) {
var name = XmlConvert.EncodeName(info.Name);
XElement rootElement = new XElement(name);
int i = 0;
foreach(var v in input)
{
XElement childElement = v.GetType().IsSimpleType2() || v.GetType().IsEnum ? new XElement(name + "_" + i, v) : _ToXml(v, null, i, name);
rootElement.Add(childElement);
i++;
}
return rootElement;
}
private static readonly Type[] WriteTypes = new[] {
typeof(string), typeof(DateTime), typeof(Enum),
typeof(decimal), typeof(Guid),
};
public static bool IsSimpleType2(this Type type) {
return type.IsPrimitive || WriteTypes.Contains(type);
}
private static readonly Type[] FlatternTypes = new[] {
typeof(string)
};
public static bool IsEnumerable(this Type type) {
return typeof(IEnumerable).IsAssignableFrom(type) && !FlatternTypes.Contains(type);
}
#endregion
}

- 160,644
- 26
- 247
- 397

- 9,037
- 3
- 34
- 50
The answer below handles IEnumerables in the way I needed and will turn this:
new
{
Foo = new[]
{
new { Name = "One" },
new { Name = "Two" },
},
Bar = new[]
{
new { Name = "Three" },
new { Name = "Four" },
},
}
into this:
<object>
<Foo><Name>One</Name></Foo>
<Foo><Name>Two</Name></Foo>
<Bar><Name>Three</Name></Bar>
<Bar><Name>Four</Name></Bar>
</object>
So here you go, yet another variant of Matthew's answer:
public static class Tools
{
private static readonly Type[] WriteTypes = new[] {
typeof(string),
typeof(Enum),
typeof(DateTime), typeof(DateTime?),
typeof(DateTimeOffset), typeof(DateTimeOffset?),
typeof(int), typeof(int?),
typeof(decimal), typeof(decimal?),
typeof(Guid), typeof(Guid?),
};
public static bool IsSimpleType(this Type type)
{
return type.IsPrimitive || WriteTypes.Contains(type);
}
public static object ToXml(this object input)
{
return input.ToXml(null);
}
public static object ToXml(this object input, string element)
{
if (input == null)
return null;
if (string.IsNullOrEmpty(element))
element = "object";
element = XmlConvert.EncodeName(element);
var ret = new XElement(element);
if (input != null)
{
var type = input.GetType();
if (input is IEnumerable && !type.IsSimpleType())
{
var elements = (input as IEnumerable<object>)
.Select(m => m.ToXml(element))
.ToArray();
return elements;
}
else
{
var props = type.GetProperties();
var elements = from prop in props
let name = XmlConvert.EncodeName(prop.Name)
let val = prop.GetValue(input, null)
let value = prop.PropertyType.IsSimpleType()
? new XElement(name, val)
: val.ToXml(name)
where value != null
select value;
ret.Add(elements);
}
}
return ret;
}
}

- 20,840
- 9
- 71
- 77
Another poster Pavel mentioned using Newtonsoft.Json methods for quick 2 line conversion
var jsonText = JsonConvert.SerializeObject(data);
XmlDocument doc = JsonConvert.DeserializeXmlNode(jsonText);
I would suggest this could actually be a single line of code :)
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
XmlDocument doc = JsonConvert.DeserializeXmlNode(JsonConvert.SerializeObject(data));
My first post to contribute to a website that always always helps a lot
Bellow is a full solution that can be used with .net core (tested using 3.1)
just call ConvertAnonymousToType.Convert("MyNewType", target, out Type newType)
The return will be an object that you can use to return inside a controller or to serialize manually (System.Xml.Serialization.XmlSerializer).
Using the object as a return Inside a controller:
1. configure the service (Startup.cs > ConfigureServices > services.AddMvcCore(options => options.OutputFormatters.Add(new XmlSerializerOutputFormatter());),
2. Target Action: use [FormatFilter] and [Route(".......{format}")],
3. Return the object
If any extra anonymous type needs to compose the reply (Metadata, Resultset, etc) DynamicTypeBuilder.CreateNewObject can be used to do service :)
Thanks again
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
namespace Configuration
{
public static class DynamicTypeBuilder
{
public static object CreateNewObject(string typeName, Dictionary<string, Type> properties, out Type newType)
{
newType = CompileResultType(typeName, properties);
return Activator.CreateInstance(newType);
}
public static Type CompileResultType(string typeName, Dictionary<string, Type> properties)
{
TypeBuilder tb = GetTypeBuilder(typeName);
ConstructorBuilder constructor = tb.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName);
//Add properties
properties.ToList().ForEach(p => CreateProperty(tb, p.Key, p.Value));
//Created Type with properties
Type objectType = tb.CreateType();
return objectType;
}
//Create Type with an standard configuration
private static TypeBuilder GetTypeBuilder(string typeName)
{
string assemblyName = typeName + "InternalAssembly";
var an = new AssemblyName(assemblyName);
AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run);
ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule");
TypeBuilder tb = moduleBuilder.DefineType(typeName,
TypeAttributes.Public |
TypeAttributes.Class |
TypeAttributes.AutoClass |
TypeAttributes.AnsiClass |
TypeAttributes.BeforeFieldInit |
TypeAttributes.AutoLayout,
null);
return tb;
}
private static void CreateProperty(TypeBuilder tb, string propertyName, Type propertyType)
{
FieldBuilder fieldBuilder = tb.DefineField("_" + propertyName, propertyType, FieldAttributes.Private);
PropertyBuilder propertyBuilder = tb.DefineProperty(propertyName, PropertyAttributes.HasDefault, propertyType, null);
MethodBuilder getPropMthdBldr = tb.DefineMethod("get_" + propertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, propertyType, Type.EmptyTypes);
ILGenerator getIl = getPropMthdBldr.GetILGenerator();
getIl.Emit(OpCodes.Ldarg_0);
getIl.Emit(OpCodes.Ldfld, fieldBuilder);
getIl.Emit(OpCodes.Ret);
MethodBuilder setPropMthdBldr =
tb.DefineMethod("set_" + propertyName,
MethodAttributes.Public |
MethodAttributes.SpecialName |
MethodAttributes.HideBySig,
null, new[] { propertyType });
ILGenerator setIl = setPropMthdBldr.GetILGenerator();
Label modifyProperty = setIl.DefineLabel();
Label exitSet = setIl.DefineLabel();
setIl.MarkLabel(modifyProperty);
setIl.Emit(OpCodes.Ldarg_0);
setIl.Emit(OpCodes.Ldarg_1);
setIl.Emit(OpCodes.Stfld, fieldBuilder);
setIl.Emit(OpCodes.Nop);
setIl.MarkLabel(exitSet);
setIl.Emit(OpCodes.Ret);
propertyBuilder.SetGetMethod(getPropMthdBldr);
propertyBuilder.SetSetMethod(setPropMthdBldr);
}
}
public static class ConvertAnonymousToType
{
public static object Convert(string typeName, object target, out Type newType)
{
var properties = GetProperties(target);
newType = DynamicTypeBuilder.CompileResultType(typeName, properties);
return Convert(newType, target);
}
public static object Convert(Type type, object target)
{
if (target.GetType().Name == typeof(List<>).Name)
{
var newListType = typeof(List<>).MakeGenericType(type);
var newList = Activator.CreateInstance(newListType);
MethodInfo addMethod = newList.GetType().GetMethod("Add");
((IList<object>)target).ToList().ForEach(e =>
{
addMethod.Invoke(newList, new object[] { ConvertObject(type, e) });
});
return newList;
}
else
{
return ConvertObject(type, target);
}
}
private static object ConvertObject(Type type, object refObject)
{
Dictionary<string, Type> properties = new Dictionary<string, Type>();
object newObject = Activator.CreateInstance(type);
var propertiesOrg = refObject.GetType().GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).ToList();
var propertiesDes = newObject.GetType().GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).ToList();
propertiesOrg.ForEach(po => propertiesDes.First(pd => pd.Name == po.Name).SetValue(newObject, po.GetValue(refObject)));
return newObject;
}
private static Dictionary<string, Type> GetProperties(object target)
{
object objectRef = target;
if (target.GetType().Name == typeof(List<>).Name) objectRef = ((List<object>)target).ToList()[0];
Dictionary<string, Type> properties = new Dictionary<string, Type>();
var lstProperties = objectRef.GetType().GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).ToList();
lstProperties.ForEach(p => properties.Add(p.Name, p.PropertyType));
return properties;
}
}
}

- 1
I found this page immensely useful. I'm moving from the old SOAP web references to something that is supported in .net standard. I've changed the code to be able to serialize it in a format that will will work with SOAP web services. Its rough, but it can convert object[]
to <anyType />
elements, other simple arrays are serialized correctly and you can pass in a namespace or have it use the XmlTypeAttribute
on your models to assign namespaces.
public static class AnonymousTypeSerializer
{
private static readonly XNamespace _xmlInstanceNs = "http://www.w3.org/2001/XMLSchema-instance";
private static readonly Type[] WriteTypes = new[] {
typeof(string), typeof(DateTime), typeof(Enum),
typeof(decimal), typeof(Guid),
};
private static readonly Dictionary<Type, string> SerializedTypeNames = new Dictionary<Type, string>()
{
{ typeof(int), "int" },
{ typeof(long), "long" }
};
/// <summary>
/// Converts an anonymous type to an XElement.
/// </summary>
/// <param name="input">The input.</param>
/// <returns>Returns the object as it's XML representation in an XElement.</returns>
public static XElement? ToXml(this object? input) => input.ToXml(null);
/// <summary>
/// Converts an anonymous type to an XElement.
/// </summary>
/// <param name="input">The input.</param>
/// <param name="element">The element name.</param>
/// <returns>Returns the object as it's XML representation in an XElement.</returns>
public static XElement? ToXml(this object? input, string? element, XNamespace? ns = null) => _ToXml(input, element, ns ?? XNamespace.None);
private static XElement? _ToXml(object? input, string? element, XNamespace? ns = null, int? arrayIndex = null, string? arrayName = null)
{
if (input == null)
return null;
if (string.IsNullOrEmpty(element))
{
string name = input.GetType().Name;
element = name.Contains("AnonymousType")
? "Object"
: arrayIndex != null
? $"{arrayName}"
: name;
}
element = XmlConvert.EncodeName(element);
var ret = new XElement(ns.GetName(element));
if (input != null)
{
var type = input.GetType();
var props = type.GetProperties();
var xmlType = type.GetCustomAttribute<XmlTypeAttribute>(true);
if (xmlType != null && xmlType.Namespace != null)
ns = xmlType.Namespace;
ret.Add(props.Select(p =>
{
var pType = Nullable.GetUnderlyingType(p.PropertyType) ?? p.PropertyType;
string name = XmlConvert.EncodeName(p.Name);
object val = pType.IsArray ? "array" : p.GetValue(input, null);
var value = pType.IsArray
? GetArrayElement(p, (Array)p.GetValue(input, null), ns)
: pType.IsSimpleType() || pType.IsEnum
? new XElement(ns.GetName(name), val)
: val.ToXml(name, ns);
return value;
}).Where(v => v != null));
}
return ret;
}
/// <summary>
/// Gets the array element.
/// </summary>
/// <param name="info">The property info.</param>
/// <param name="input">The input object.</param>
/// <returns>Returns an XElement with the array collection as child elements.</returns>
private static XElement GetArrayElement(PropertyInfo info, Array? input, XNamespace ns)
{
string name = XmlConvert.EncodeName(info.Name);
if (input == null)
return null;
int arrayCount = input.GetLength(0);
var elementType = input.GetType().GetElementType();
bool isAnyType = elementType == typeof(object);
XElement rootElement;
if (isAnyType)
rootElement = new XElement(ns + name, new XAttribute(XNamespace.Xmlns + "xsi", _xmlInstanceNs));
else
rootElement = new XElement(ns + name);
for (int i = 0; i < arrayCount; i++)
{
object val = input.GetValue(i);
if (isAnyType)
{
var valType = val.GetType();
var xmlType = valType.GetCustomAttribute<XmlTypeAttribute>(true);
var valNs = ns;
if (xmlType != null && xmlType.Namespace != null)
valNs = xmlType.Namespace;
// Create anyType element
var childElement = new XElement(ns + "anyType", new XAttribute(XNamespace.Xmlns + $"p{rootElement.Elements().Count()}", valNs));
// Create type attribute
string nsPrefix = childElement.GetPrefixOfNamespace(valNs);
childElement.Add(new XAttribute(_xmlInstanceNs + "type",
!string.IsNullOrEmpty(nsPrefix)
? $"{nsPrefix}:{valType.Name}"
: valType.Name));
// Create child elements
var inner = _ToXml(val, null, ns, i, "anyType");
childElement.Add(inner!.Elements());
// Done
rootElement.Add(childElement);
}
else
{
if (!SerializedTypeNames.TryGetValue(elementType, out string typeName))
typeName = elementType.Name;
rootElement.Add(elementType.IsSimpleType()
? new XElement(ns.GetName(typeName.ToLower()), val)
: _ToXml(val, null, ns, i, typeName));
}
}
return rootElement;
}
public static bool IsSimpleType(this Type type) =>
type.IsPrimitive || WriteTypes.Contains(type);
}

- 396
- 4
- 10