【问题标题】:XML serializing Enum type propertiesXML 序列化枚举类型属性
【发布时间】:2018-04-05 12:22:46
【问题描述】:

我正在尝试对包含枚举属性的类进行 XML 序列化。如果该属性是使用特定枚举声明的,则它可以正常工作。但是我需要属性是枚举类型,所以我可以将它设置为不同的枚举类型。但是,执行此操作时出现异常。

类型 [namespace].Simple 不能在此上下文中使用。

我在枚举定义上尝试了不同的属性,但到目前为止还没有做到正确。有没有办法做到这一点?

public enum Simple : byte
{
    one = 0x01,
    two = 0x02,
    three = 0x03
}

public class Foo
{
    public Enum Simple { get; set; }
}

public class Program
{
    static void Main(string[] args)
    {
        using (var writer = XmlWriter.Create(Console.OpenStandardOutput()))
        {
            try
            {
                var foo = new Foo
                {
                    Simple = Simple.three
                };
                var serializer = new XmlSerializer(foo.GetType());
                serializer.Serialize(writer, foo);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }
        Console.ReadLine();
    }
}

【问题讨论】:

    标签: c# xml serialization enums


    【解决方案1】:

    您可以尝试在要序列化的 DataContract 上设置 EnumMember 属性,以获取更具体的信息访问 https://msdn.microsoft.com/en-us/library/system.runtime.serialization.enummemberattribute(v=vs.110).aspx

    【讨论】:

      【解决方案2】:

      Enum 是抽象的,不能序列化。 this answer 中介绍了一种可能的解决方法。

      enum 的常见原始基类型是int(默认情况下,也可以是字节或长整数)。
      所以你也可以简单地使用这个整数基类型,比如你的Foo类中的byte Simple

      如果您需要字符串表示形式出现在 xml 中(与枚举字段名称相同),请将其公开为 string Simple

      【讨论】:

      • 问题是不同枚举中的成员可以具有相同的值,即我需要知道已序列化的枚举类型。使用字符串时,是否可以在 XAML 中获取“[Enum].[Member]”,并在反序列化时也使用它?
      • 我不这么认为。也许其他人有更好的主意,在这种情况下我要做的是在序列化中包含两个字段:一个是枚举类型名称,另一个是相应的字节/整数值。然后像Enum.Parse<type>(value)一样在实际的xml反序列化之后进行部分反序列化。应用@Asw 的解决方案并将类型名称作为属性值的一部分也可以工作。但这也不能让您免于一些自定义反序列化工作。
      • 有趣的想法。将调查... :-)
      【解决方案3】:

      基于dlatikay关于将枚举拆分为枚举类型和成员名称两个字符串的想法,我提出了以下解决方案。该示例将 Foo 对象转换为 XML 字符串,然后再次转换回新的 Foo 对象。

      public enum SimpleEnum : byte
      {
          one = 0x01,
          two = 0x02,
          three = 0x03
      }
      
      public class Foo
      {
          private Enum _simple;
          [XmlIgnore]
          public Enum Simple
          {
              get { return _simple; }
              set {
                  _simple = value;
                  var type = Simple.GetType();
                  var underlyingType = Enum.GetUnderlyingType(type);
                  EnumType = Simple.GetType().FullName;
                  EnumMember = Simple.ToString();
              }
          }
      
          private string _enumType;
          public string EnumType
          {
              get { return _enumType; }
              set { _enumType = value; }
          }
      
          private string _enumMember;
          public string EnumMember
          {
              get { return _enumMember; }
              set {
                  _enumMember = value;
                  _simple = (Enum)Enum.Parse(Type.GetType(EnumType), EnumMember);
              }
          }
      }
      
      public class Program
      {
          static void Main(string[] args)
          {
              var str = new StringBuilder();
              using (var writer = XmlWriter.Create(str))
              {
                  try
                  {
                      var foo = new Foo
                      {
                          Simple = SimpleEnum.three
                      };
                      var serializer = new XmlSerializer(typeof(Foo));
                      serializer.Serialize(writer, foo);
                      Console.WriteLine(str.ToString());
                  }
                  catch (Exception ex)
                  {
                      Console.WriteLine(ex.ToString());
                  }
              }
      
              using (TextReader reader = new StringReader(str.ToString()))
              {
                  try
                  {
                      var serializer = new XmlSerializer(typeof(Foo));
                      var foo = (Foo)serializer.Deserialize(reader);
                  }
                  catch (Exception ex)
                  {
                      Console.WriteLine(ex.ToString());
                  }
              }
              Console.ReadLine();
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-26
        相关资源
        最近更新 更多