Сериализация enum не работает - PullRequest
2 голосов
/ 10 февраля 2012

Я использую .NET 3.5 для этого.

У меня есть перечисление:

[System.SerializableAttribute()]
public enum MyEnum
{
    [System.Xml.Serialization.XmlEnumAttribute("035")]
    Item1,
    Item2
}

Я использую это перечисление в классе:

[System.SerializableAttribute()]
public class Employee
{
    public int Id { get; set; }
    public string Name { get; set; }
    public MyEnum MyEnum { get; set; }
}

Теперь я хочу создать новый экземпляр Eplomyee, установить свойство MyEnum, приведя его к строке. Затем сериализуйте его и сохраните в файле.

Employee bob = new Employee() {Id = 1, Name = "Bob"};
bob.MyEnum = (MijnEnum)Enum.Parse(typeof(MyEnum), string.Format(CultureInfo.InvariantCulture, "{0}", "035"));

XmlSerializer serializer = new XmlSerializer(typeof(Employee));
FileInfo fi = new FileInfo(@"C:\myfile.xml");
using (FileStream stream = fi.OpenWrite())
{
    XmlWriterSettings xmlWriterSettings = new XmlWriterSettings { Encoding = Encoding.UTF8, OmitXmlDeclaration = true, Indent = true };
    using (XmlWriter writer = XmlWriter.Create(stream, xmlWriterSettings))
    {
        serializer.Serialize(writer, bob); // this is place where it goes wrong
    }
}

Если я отлаживаю это, я вижу, что значение bob.MyEnum равно 35

Когда я пытаюсь сериализоваться, я получаю исключение:

Произошла ошибка при создании документа XML.

Ошибка проверки экземпляра: '35' не является допустимым значением для WindowsFormsApplication.MyEnum.

Что не так и как я могу это решить?

Ответы [ 3 ]

3 голосов
/ 10 февраля 2012

Давайте начнем:

[System.SerializableAttribute()] // useless, valuetype is implicitly so
public enum MyEnum
{
    [System.Xml.Serialization.XmlEnumAttribute("035")]
    Item1,
    Item2
}

Теперь XmlEnumAttribute контролирует сериализацию и десериализацию этого значения в XML.

Это ничего не значит с отдыхом в вашем коде! (извините за заглавные буквы, но никто другой, похоже, не понял).

Таким образом, когда сериализуется значение MyEnum.Item1, будет выдано «035».

Теперь проблема в том, как вы хотите назначить это.

Это просто. Просто назначьте, как обычно. Ни один из этих атрибутов не меняет семантику нормального кода, все остается неизменным.

Пример:

Employee bob = new Employee() {Id = 1, Name = "Bob", MyEnum = MyEnum.Item1};

Абсолютно нет причин, по которым Enum.Parse следует даже рассматривать здесь. Тип и значение перечисления статически известны.

Если вы хотите использовать Enum.Parse, используйте его как обычно, например:

Enum.Parse(typeof(MyEnum), "Item1")
3 голосов
/ 10 февраля 2012

Это происходит потому, что Enums внутренне хранятся как int.Следовательно, ваше заявление bob.MyEnum = (MijnEnum)Enum.Parse(typeof(MyEnum), string.Format(CultureInfo.InvariantCulture, "{0}", "035")); выполняется без проблем.При отладке значение bob.MyEnum равно 35.Когда вы десериализуете это, десериализатор ищет совпадение enum со значением int 35, которого там нет, так как вы указываете Item1 и Item2.Следовательно, вы получаете ошибку.

Это сработает

 bob.MyEnum = (MyEnum)Enum.Parse(typeof(MyEnum), "35");

 public enum MyEnum {
   Item1 = 35,
   Item2
 }

В идеале вы должны делать это

 bob.MyEnum = (MyEnum)Enum.Parse(typeof(MyEnum), "Single");

 public enum MyEnum {
   [System.Xml.Serialization.XmlEnumAttribute("Single")]
   Item1,
   Item2
 }

Надеюсь, это вам поможет.

0 голосов
/ 10 февраля 2012

Я изменил синтаксический анализ.

Я использовал отражение для разбора строки на перечисление, как описано в этой статье: http://www.codeguru.com/csharp/csharp/cs_syntax/enumerations/article.php/c5869

И теперь это работает.

...