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)
}