C # десериализация перечислений из целых чисел - PullRequest
13 голосов
/ 30 марта 2012

Возможно ли десериализовать перечисление из int в c #. например Если у меня есть следующий класс:

class Employee
{
   public string Name { get; set;}
   public int EmployeeTypeID { get; set;}
}

Я могу легко создать это из XML

   <Employee>
       <Name>Joe Bloggs</Name>
       <EmployeeTypeID>1</EmployeeTypeID>
   </Employee>

используя что-то вроде этого:

Employee employee = (Employee)new XmlSerializer(typeof(Employee)).Deserialize(XmlReader);

С очень небольшим количеством работы это позволяет мне использовать один универсальный сервис, который я могу использовать для всех объектов базы данных, передавая команду select, строку подключения и тип для получения и получения массива объектов без необходимости дальнейшего сопоставления , Однако я рассталась с перечислениями. Предположим, что вместо целого числа EmployeeType является перечислением:

public enum EmployeeTypeEnum
{
   Admin = 1,
   Sales = 2
}

так что мой класс становится:

class Employee
{
   public string Name { get; set;}
   public EmployeeTypeEnum EmployeeTypeID { get; set;}
}

Могу ли я использовать тот же XML и заставить c # распознать, что значение int EmployeeTypeID в xml должно соответствовать значению int перечисления? Существуют и другие подобные вопросы, но ни один из них не имеет очень удовлетворительного ответа, они довольно старые и включают массовые изменения в коде. Я надеюсь на лучшее решение ...

Как возможное отдельное примечание (и немного в ожидании некоторых ответов), лучше ли избегать использования перечислений для этого? Должен ли я использовать пары ключ-значение? Я всегда использовал бы пары «ключ-значение» (или аналогичные), если есть вероятность изменений, но в этом случае EmployeeType фиксирован и никогда не изменится.

Ответы [ 3 ]

20 голосов
/ 30 марта 2012

Теоретически (= я не пробовал), добавление атрибута XmlEnum к вашим значениям перечисления должно помочь:

public enum EmployeeTypeEnum 
{ 
    [XmlEnum("1")] Admin = 1, 
    [XmlEnum("2")] Sales = 2 
} 

Это говорит XmlSerializer, что значениеEmployeeTypeEnum.Admin должен быть сериализован как строка 1 и наоборот (что вам нужно).

Относительно вашего примечания: я не вижу использования enumsздесь как проблема.Если значения в базе данных являются целыми числами и имеют фиксированное значение, перечисления являются хорошим решением и, кроме того, служат документацией для значений базы данных.

3 голосов
/ 30 марта 2012

Если у вас xml в этом формате:

<Employee>
  <Name>Shiv</Name>
  <EmployeeTypeID>Sales</EmployeeTypeID>
</Employee>

Это будет работать как есть. Если вы украсите свой enum атрибутом XmlEnum следующим образом:

    public enum EmployeeTypeEnum
{
    [XmlEnum("1")]
    Admin = 1,
    [XmlEnum("2")]
    Sales = 2
}

Затем вы можете использовать целочисленные значения в вашем XML-файле, и они будут автоматически сопоставлены с перечислением.

Лично я предпочитаю использовать перечисления в подобных случаях. Даже если элементы в перечислении могут со временем увеличиваться, я предпочитаю использовать перечисления. Фактически, такие перечисления являются кодом, сгенерированным из базы данных, поэтому в коде вы не работаете с идентификаторами (гораздо более читаемыми).

0 голосов
/ 28 октября 2015

В XML-файле используйте именованную константу вместо целочисленного значения. Это будет работать просто отлично.

<Employee>
       <Name>Joe Bloggs</Name>
       <EmployeeTypeID>Admin</EmployeeTypeID>
</Employee>
...