XmlSerialize поле Enum Flag

У меня есть это:

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

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

Я хочу Xml serialize Formulaire

Если я запустил:
_infoAbonne = InfoAbonne.name | InfoAbonne.email;

В моем Xml-результате я получаю только:

<InfoAbonne>email</InfoAbonne>

Ответ 1

Несмотря на то, что вы добавили атрибут Flags к вашему перечислению, вам все равно нужно убедиться, что значения равны двум:

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

См. рекомендации, изложенные в разделе Примечания документации .

Ответ 2

Основная идея с такими проблемами состоит в том, чтобы сериализовать поле поддержки, которое имитирует поле, которое вы хотите сериализовать. Тот же принцип может применяться к сложным типам, таким как Bitmaps и т.д. Например, вместо сериализации поля Enum напрямую вы можете сериализовать поле поддержки типа int:

// 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; } 
} 

С уважением,

Ответ 3

р. Ответ ABT лучше, чем выбранный ответ. Да, необходимо иметь значения по степеням 2, но это не относится к проблемам XML-сериализации.

Перечисления сериализуются очень по-разному, чем большинство объектов. Перечисления будут XML-сериализованы по их имени (ser(MyEnumProperty.[Name]) = "[Name]") вместо использования имени name (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
}

Я добавил новые значения Enum, которые, возможно, были использованы (как DLL) в других проектах. О, вау... что это за ошибки?

Вы больше не можете десериализовать свою новейшую версию перечисления в более старую версию с сериализацией XML (Binary Serialization должно по-прежнему работать)

Взгляните на метод ToEnum от Microsoft. Это предотвращает просмотр идентификатора (скажем, "Третий" в обновленном перечислении), поскольку он не существует в исходном перечислении. Также обратите внимание, что будет выброшена ошибка, которая может сломать ваш проект, если он не обрабатывается.

Будьте уверены, всегда производите сериализацию и десериализацию по значению при предоставлении возможности. Вот почему мы начинаем использовать объекты, такие как помеченные перечислением. Такие объекты, как отмеченные флажки, уменьшают обратную совместимость и проблемы с зависимостью.

Ответ 4

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