using System.Collections.Generic;
using System.Xml.Serialization;
using System.Diagnostics;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Text.RegularExpressions;
using System.Globalization;
using System.ComponentModel.DataAnnotations;
using System.Collections;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
[System.Xml.Serialization.XmlEnumAttribute("01010101")]
[System.Xml.Serialization.XmlEnumAttribute("10101500")]
[System.Xml.Serialization.XmlEnumAttribute("Flag0")]
[System.Xml.Serialization.XmlEnumAttribute("Flag1")]
[System.Xml.Serialization.XmlEnumAttribute("Flag2")]
[System.Xml.Serialization.XmlEnumAttribute("Flag7")]
[System.Xml.Serialization.XmlEnumAttribute("Flag14")]
public static partial class XmlEnumExtensions
public static TEnum FromReflectedXmlValue<TEnum>(this string xml) where TEnum : struct, IConvertible, IFormattable
var obj = (from field in typeof(TEnum).GetFields(BindingFlags.Public | BindingFlags.Static)
from attr in field.GetCustomAttributes<XmlEnumAttribute>()
where attr != null && attr.Name == xml
select field.GetValue(null)).SingleOrDefault();
return (TEnum)Enum.Parse(typeof(TEnum), xml, false);
public static partial class XmlExtensions
noStandardNamespaces = new XmlSerializerNamespaces();
noStandardNamespaces.Add("", "");
readonly static XmlSerializerNamespaces noStandardNamespaces;
internal const string RootNamespace = "XmlExtensions";
internal const string RootName = "Root";
public static TEnum FromXmlValue<TEnum>(this string xml) where TEnum : struct, IConvertible, IFormattable
var element = new XElement(XName.Get(RootName, RootNamespace), xml);
return element.Deserialize<XmlExtensionsEnumWrapper<TEnum>>().Value;
public static T Deserialize<T>(this XContainer element, XmlSerializer serializer = null)
using (var reader = element.CreateReader())
object result = (serializer ?? new XmlSerializer(typeof(T))).Deserialize(reader);
public static string ToXmlValue<TEnum>(this TEnum value) where TEnum : struct, IConvertible, IFormattable
var root = new XmlExtensionsEnumWrapper<TEnum> { Value = value };
return root.SerializeToXElement().Value;
public static XElement SerializeToXElement<T>(this T obj)
return obj.SerializeToXElement(null, noStandardNamespaces);
public static XElement SerializeToXElement<T>(this T obj, XmlSerializer serializer, XmlSerializerNamespaces ns)
var doc = new XDocument();
using (var writer = doc.CreateWriter())
(serializer ?? new XmlSerializer(obj.GetType())).Serialize(writer, obj, ns);
[XmlRoot(XmlExtensions.RootName, Namespace = XmlExtensions.RootNamespace)]
[XmlType(IncludeInSchema = false)]
public class XmlExtensionsEnumWrapper<TEnum>
public TEnum Value { get; set; }
class EnumValue<TEnum> where TEnum : struct, IConvertible, IFormattable
public TEnum ItsEnumValue;
public static void Test()
var obj = new EnumValue<myEnum>();
obj.ItsEnumValue = "01010101".FromReflectedXmlValue<myEnum>();
obj.ItsEnumValue = "01010101".FromXmlValue<myEnum>();
TestDeserialization<myEnum>();
TestReflection<myEnum>();
TestDeserialization<myFlagsEnum>();
TestReflection<myFlagsEnum>();
Console.WriteLine("Unable to deserialize all values of {0} using reflection.", typeof(myFlagsEnum));
public static void TestDeserialization<TEnum>() where TEnum : struct, IConvertible, IFormattable
Console.WriteLine(string.Format("Testing {0} using deserialization...", typeof(TEnum)));
foreach (TEnum val in GetAllEnums<TEnum>())
var xml = val.ToXmlValue();
var val2 = xml.FromXmlValue<TEnum>();
Console.WriteLine(string.Format("Enum ({0}) has XML: {1}", val, xml));
Assert.IsTrue(val.Equals(val2));
Console.WriteLine(string.Format("Successfully tested {0}.", typeof(TEnum)));
public static void TestReflection<TEnum>() where TEnum : struct, IConvertible, IFormattable
Console.WriteLine(string.Format("Testing {0} using reflection...", typeof(TEnum)));
foreach (TEnum val in GetAllEnums<TEnum>())
var xml = val.ToXmlValue();
var val3 = xml.FromReflectedXmlValue<TEnum>();
Assert.IsTrue(val.Equals(val3));
Console.WriteLine(string.Format("Successfully tested {0}.", typeof(TEnum)));
static IEnumerable<TEnum> GetAllEnums<TEnum>() where TEnum : struct, IConvertible, IFormattable
if (typeof(TEnum).IsDefined(typeof(FlagsAttribute), false))
return GetAllFlagsEnums<TEnum>();
return Enum.GetValues(typeof(TEnum)).Cast<TEnum>();
static IEnumerable<TEnum> GetAllFlagsEnums<TEnum>() where TEnum : struct, IConvertible, IFormattable
if (typeof(TEnum).BaseType != typeof(Enum))
throw new ArgumentException("T must be an Enum type");
var values = Enum.GetValues(typeof(TEnum)).Cast<TEnum>().Select(e => ToUInt64(e)).ToArray();
var valuesInverted = values.Select(v => ~v).ToArray();
var result = new List<TEnum>();
for (int i = 0; i < values.Length; i++)
for (ulong i = 0; i <= max; i++)
ulong unaccountedBits = i;
for (int j = 0; j < valuesInverted.Length; j++)
unaccountedBits &= valuesInverted[j];
if (unaccountedBits == 0)
result.Add((TEnum)Enum.ToObject(typeof(TEnum), i));
if (string.IsNullOrEmpty(Enum.GetName(typeof(TEnum), (TEnum)Enum.ToObject(typeof(TEnum), 0))))
result.Remove((TEnum)Enum.ToObject(typeof(TEnum), 0));
result.Remove((TEnum)Enum.ToObject(typeof(TEnum), 0));
static ulong ToUInt64<TEnum>(TEnum value) where TEnum : struct, IConvertible, IFormattable
TypeCode typeCode = value.GetTypeCode();
result = (UInt64)value.ToInt64(CultureInfo.InvariantCulture);
result = value.ToUInt64(CultureInfo.InvariantCulture);
throw new InvalidOperationException();
public class AssertionFailedException : System.Exception
public AssertionFailedException() : base() { }
public AssertionFailedException(string s) : base(s) { }
public static class Assert
public static void IsTrue(bool value)
throw new AssertionFailedException("failed");
public static void Main()