XmlSerialize一个Enum Flag字段

时间:2012-01-23 11:27:59

标签: c# .net-4.0 xml-serialization

我有这个:

    [Flags]
    public enum InfoAbonne{civilite,name,firstname,email,adress,country }

    public class Formulaire
    {
      private InfoAbonne _infoAbonne{ get; set;}
      public Formulaire()
      {}
    }

我想要Xml序列化Formulaire

如果我初始化:
_infoAbonne = InfoAbonne.name | InfoAbonne.email;

在我的Xml结果中,我只得到:

<InfoAbonne>email</InfoAbonne>

4 个答案:

答案 0 :(得分:15)

即使您在枚举中添加了Flags属性,仍然需要确保值为2的幂:

[Flags]
public enum InfoAbonne
{
    civilite = 1,
    name = 2,
    firstname = 4,
    email = 8,
    adress = 16,
    country = 32
}

请参阅documentation备注部分中列出的指南。

答案 1 :(得分:8)

这些问题的基本思想是序列化一个模拟你想要序列化的字段的后备字段。相同的原则可以应用于复杂类型,如位图等...例如,您可以序列化int类型的支持字段,而不是直接序列化Enum字段:

// Disclaimer: Untested code, both in execution and compilation
[Flags]      
public enum InfoAbonne 
{
    civilite = 0x1, // Increment each flag value by *2 so they dont conflict
    Name=0x2,
    firstname=0x4,
    email=0x8,
    adress=0x10,
    country=0x20 
}  

// Don't serialize this field
[XmlIgnore]
private InfoAbonne _infoAbonne { get; set;} 

// Instead serialize this field as integer
// e.g. name | email will equal 0xA in hex, or 10 in dec
[XmlElement("InfoAbonne")]
private InfoAbonneSerializer 
{ 
    get { return (int)_infoAbonne; } 
    set { _infoAbonne= (InfoAbonne) value; } 
} 

致以最诚挚的问候,

答案 2 :(得分:0)

博士。 ABT的回答比选择的回答要好。是的,拥有2的幂值是必要的,但这并不是XML序列化问题所特有的。

枚举的序列化方式与大多数对象截然不同。枚举将按名称(ser(MyEnumProperty.[Name]) = "[Name]")进行XML序列化,而不是使用名称(ser(MyEnumProperty.[Name]) = 8)的值。

// Version 1.0
[Flags]      
public enum MyEnum
{
    None = 0,
    First = 1,
    Second = 2,
    All = First | Second
}

public MyEnum MyEnumProperty = MyEnum.All;

如果您要序列化MyEnumProperty,则会获得<MyEnum> All </MyEnum>。但是,如果您序列化(int)MyEnumProperty,则会获得<int> 3 </int>。我想提一下为什么要知道这是非常必要的......

// Version 2.0
[Flags]      
public enum MyEnum
{
    None = 0,
    First = 1,
    Second = 2,
    Third = 4, // <---
    All = First | Second | Third
}

我添加了新的枚举值,这些值可能已在其他项目中使用(作为DLL)。哦哇......这些错误是什么?

您无法再将最新版本的枚举反序列化为旧版本的XML序列化(Binary Serialization仍应有效)!

查看Microsoft的ToEnum方法。这可以防止查看ID(例如,更新的枚举中的#34;第三&#34;)因为它不存在于原始枚举中。另请注意,如果未处理该项目,将会抛出错误。

在有机会的情况下,保持安全,始终按值进行序列化和反序列化。这就是我们开始使用标记枚举等对象的原因。标记枚举之类的对象会降低向后兼容性和依赖性问题。

答案 3 :(得分:0)

[Flags]
public enum InfoAbonne
{
    civilite = (1 << 0),
    name = (1 << 1),
    firstname = (1 << 2),
    email = (1 << 3),
    adress = (1 << 4),
    country = (1 << 5)
}