Возможно ли сериализовать объект в строковое представление вместо гиперопекательного вложенного xml?

#c# #serialization

#c# #сериализация

Вопрос:

У меня есть класс, который описывает отношение двух чисел, он принимает строку, которая может быть преобразована в десятичную по желанию программой. Я бы хотел, чтобы он был сериализован в файл настроек, чтобы пользователь мог на досуге вводить значения (например, 1/2, 4/5, 6/3, что угодно), которые будут сериализованы следующим образом.

 <ZoneInterface>
    <Ratio1>
        <Value>0</Value>
    </Ratio1>
    <Ratio2>
        <Value>2/3</Value>
    </Ratio2>
</ZoneInterface>
  

Если это вообще возможно, поскольку единственное, что на самом деле сериализуется, — это строка значения, я бы предпочел, чтобы она сериализовалась следующим образом

 <ZoneInterface>
    <Ratio1>0</Ratio1>
    <Ratio2>2/3</Ratio2>
</ZoneInterface>
  

Класс довольно прост — есть ли какой-либо способ, который я могу добавить к нему, чтобы заставить его сериализовать / десериализовать в более сжатом manor?

 [Serializable]
public class Ratio
{
    private static Regex ValidationRegex = new Regex(@"^d /d $");
    public string Value
    {
        get
        {
            return denominator == 1 ?
                $"{numerator}" :
                $"{numerator}/{denominator}";
        }
        set
        {
            if (ValidationRegex.IsMatch(value))
            {
                var args = value.Split('/');
                numerator = Int32.Parse(args[0]);
                denominator = Int32.Parse(args[1]);
            }
            else if (int.TryParse(value, out var result))
            {
                numerator = resu<
                denominator = 1;
            }
            else
            {
                throw new InvalidDataException($"Unable to parse ratio {value}, must be of form "[integer]/[integer]"");
            }
            if (denominator == 0)
            {
                throw new InvalidDataException($"Unable to parse ratio {value}, cannot divide by zero");
            }
        }
    }
    private int numerator;
    private int denominator;

    public static implicit operator Ratio(string str)
    {
        return new Ratio() { Value = str };
    }

    public Decimal Decimal => ((decimal)numerator / (decimal)denominator);
}
  

Комментарии:

1. Привет, я думаю, вы можете использовать атрибут XmlArrayItemAttribute: learn.microsoft.com/en-us/dotnet/standard/serialization /…

2. Попробуйте вместо этого формат Json. Проверьте эту ссылку w3schools.com/js/js_json_syntax.asp

Ответ №1:

Вы могли бы использовать XmlTextAttribute в своем свойстве Value. Минимальный рабочий пример смотрите ниже. Вы можете удалить атрибут, чтобы проверить его поведение.

 using System;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

namespace SomeNamespace
{
    public class Program
    {
        static void Main()
        {
            Ratio r = new Ratio { Value = "2/3" };
            XmlSerializer serializer = new XmlSerializer(typeof(Ratio));
            StringBuilder sb = new StringBuilder();
            using (XmlWriter writer = XmlWriter.Create(sb))
            {
                serializer.Serialize(writer, r);
            }
            Console.Write(sb);
            // prints as <Ratio>2/3</Ratio> (if you can ignore the xlmns:xsi clutter)
            // without [XmlText], would print as <Ratio><Value>2/3</Value></Ratio>
        }
    }
   
    public class Ratio
    {
        [XmlText]
        public string Value { get; set; } = string.Empty;
    }
}