[C #] I want to make enum serialization cool!

1 minute read

Introduction

When serializing an enumeration using C # System.Xml.Serialization.XmlSerializer, the name of the identifier is not output as it is (?).
Therefore, I tried to make it possible to customize the character string that is output when the enumeration type is serialized.

code


using System;
using System.Reflection;
using System.Xml.Serialization;

namespace Qiita
{
  //Attribute for assigning an arbitrary string to the enumeration
  public class CustomTextAttribute : Attrubute
  {
    public string StringValue { get; protected set; }

    public CustomTextAttribute(string value)
    {
      this.StringValue = value;
    }
  }

  //Enumerator
  public enum Wochentage
  {
    [CustomText("mo")]
    Montag,

    [CustomText("di")]
    Dienstag,

    [CustomText("mi")]
    Mittwoch,

    [CustomText("do")]
    Donnerstag,

    [CustomText("fr")]
    Freitag,

    [CustomText("sa")]
    Samstag,

    [CustomText("so")]
    Sonntag
  }

  //Wrapper for serialization
  [Serializable]
  public class EnumWrapper<T> where T : Enum
  {
    protected T value;

    [XmlText]
    public string Value
    {
      get
      {
        //Get attributes with reflection
        var type = this.value.GetType();
        var fieldInfo = type.GetField(this.value.ToString());
        if (fieldInfo == null) return this.value.ToString();

        var attrs = fieldInfo.GetCustomAttributes<CustomTextAttribute>() as CustomTextAttribute[];
        return attrs.Length > 0 ? attrs[0].StringValue : this.value.ToString();
      } // get
      set
      {
        //I didn't know how to do it efficiently, so I'll do my best
        foreach (T val in Enum.GetValues(typeof(T)))
        {
          if (val.ToString<CustomTextAttribute>() == value)
            this.value = val;
            return;
        }
      } // set
    }

    public EnumWrapper() { }

    public EnumWrapper(T val)
    {
      this.value = val;
    }

    //Define implicit type conversion with enumeration
    public static implicit operator EnumWrapper<T>(T val)
      => new EnumWrapper<T>(val);

    public static implicit operator T(EnumWrapper<T> val)
      => val.value;
  } // public class EnumWrapper<T> where T : Enum
} // namespace Qiita

How to use

Simply change the type of the enumeration (let’s call it Wochentage) in the types to be serialized to ʻEnumWrapper ` and it will be serialized using the value specified by the `CustomText` attribute. It can be implicitly converted to the type before the change (`Wochentage`), so no other code needs to be changed.

Other

This time I wrote it in the property, but I also said that I created multiple classes corresponding to CustomTextAttribute, defined the extension method ToString <T> and converted it to a character string. You can (for displaying on the UI).

References

-Assign a string to C #> enum.