Свойство должно быть установлено только сериализатором - PullRequest
3 голосов
/ 18 октября 2010

У меня есть класс, который взаимодействует с API и должен выполнить некоторые преобразования для любых данных, которых он касается.Этот класс также эквивалентен:

public class SerializeMe
{
    public SerializeMe(string someString)
    {
        _someString = someString;
    }

    private string _someString;
    public string TransformedValue
    {
        get { _someString = TransformToSomething();
              return _someString; }
        set { _someString = value; }
    }
}

Для моих абонентов API я регистрирую каждый запрос и ответ путем сериализации этих классов.Они действуют почти как XML-схемы.

Теперь все работает отлично, моя единственная проблема в том, что кто-то теоретически может попытаться установить и в конечном итоге не получить ожидаемые результаты.В основном это проблема дизайна, просто пытающаяся сделать мой код ответственным.Я хотел бы иметь возможность использовать закрытый набор для этого, но XmlSerializer жалуется на это.

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

Также, если нет опции, сделать свойство устаревшим - опция.Есть ли другой более подходящий атрибут для использования?

Ответы [ 3 ]

2 голосов
/ 18 октября 2010

XmlSerializer делает многое из коробки, но чтобы получить гибкость, которую вы хотите, после того, как вы должны использовать интерфейс IXmlSerializable .XmlSerializer будет смотреть на объект и, если он реализует IXmlSerializable, он будет вызывать методы объекта, предоставляемого интерфейсом.Да, это больше работы, но у вас есть более детальный подход к тому, как ваш объект де / сериализован.

2 голосов
/ 18 октября 2010

Это проблема с XmlSerializer, но прекрасно работает с DataContractSerialzer (который также может работать без ctor без параметров, который нужен XmlSerializer) Просто пометьте тип как [DataContract], а поле (не свойство) как [DataMember].

[DataContract]
public class SerializeMe
{
    public SerializeMe(string someString)
    {
        _someString = someString;
    }
    [DataMember]
    private string _someString;
    public string TransformedValue
    {
        get { _someString = TransformToSomething();
              return _someString; }
        private set { _someString = value; }
    }
}
0 голосов
/ 18 октября 2010

К сожалению, XmlSerializer может сериализовать свойства только с общедоступными методами получения / установки (если, конечно, вы не указали свою собственную сериализацию через IXmlSerializable).

Единственный обходной путь, который я использовал время от времени (и это хак и не соответствует рекомендациям по дизайну .NET, так что я совсем не люблю это делать) - иметь открытое свойство с пустым установщиком, а затем использовать другой метод для установки закрытой резервной переменной:

public class SerializeMe
{
    private string _someString;
    public string SomeString
    {
        get
        {
            _someString = TransformToSomething();
            return _someString;
        }
        set { }
    }

    public void SetString(string val) { _someString = val; }
}

Очевидно, что IXmlSerializable - это больше работы, но это определенно лучшее решение в долгосрочной перспективе (не говоря уже о том, что это не хак).

...