Страницы

Поиск по вопросам

пятница, 20 декабря 2019 г.

Xml сериализация объектов со свойствами только для чтения

#c_sharp #xml #сериализация




При сериализации массива из объектов этого класса все атрибуты игнорируются, если
у них нет setter'а. Вопрос: как решить проблему с этим явлением; класс не предусмотрен
для изменения данных.

/// 
/// Представляет поля и методы для работы с абстракцией осциллятора.
/// 
[Serializable]
public class Oscillator : IMixer
{
    private Boolean enable;
    /// 
    /// Состояние вкл / выкл.
    /// 
    [XmlAttribute]
    public Boolean Enable
    {
        get
        {
            return enable;
        }
        set
        {
            enable = value;
        }
    }


    private Int32 volume;
    /// 
    /// Процентная громкость.
    /// 
    [XmlAttribute]
    public Int32 Volume
    {
        get
        {
            return volume;
        }
    }



    public Oscillator()
    {

    }


    public Oscillator(Boolean enable, Int32 volume)
    {
        this.enable = enable;
        this.volume = volume;
    }
}


    //Вот, сама сериализация, если интересно.
    /// 
    /// Сохраняет пресет в Xml-файл.
    /// 
    /// 
    /// Путь к файлу.
    /// 
    /// 
    /// Массив осцилляторов для записи его в пресет.
    /// 
    public void SavePreset(String fileName, Oscillator[] oscs)
    {
        try
        {
            XmlSerializer serializer = new XmlSerializer(typeof(Oscillator[]));
            using (Stream stream = new FileStream(fileName, FileMode.Create, FileAccess.Write))
            {
                serializer.Serialize(stream, oscs);
                //for (Int32 i = 0; i < oscs.Length; i++)
                //{
                //    serializer.Serialize(stream, oscs[i]);
                //}
            }
        }
        catch
        {
            throw new PresetException(PresetException.SaveError);
        }
    }

    


Ответы

Ответ 1



Никак, это ограничение XmlSerializer. Only public properties and fields can be serialized. Properties must have public accessors (get and set methods). If you must serialize non-public data, use the DataContractSerializer class rather than XML serialization. В оригинальном ответе, как и в документации, советуют воспользоваться более гибким DataContractSerializer. Вариант с вырожденным сеттером, думаю, рассматривать не будем.

Ответ 2



Никак. Но вам это и не нужно. Вы должны иметь отдельные классы для сериализации/десериализации (и вообще любой транспортировки данных - DTO) и для бизнес-логики (POCO). И я рекомендую вам реализовать такое разделение как можно раньше, это позволит избежать глобальных ломающих изменений по мере развития проекта. Ссылка по теме: Наглядный пример различия DTO, POCO (POJO) и Value Object

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

Отправить комментарий