2010-10-18 4 views
3

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

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 жалуется на это.

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

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

ответ

2

Это боль с 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

Также DataContractSerializer более совершенен, чем XmlSerializer, и может обрабатывать как поля, так и свойства. Один недостаток заключается в том, что вы не можете контролировать структуру Xml, поэтому, если вам нужно, чтобы он был в определенном формате, вы не сможете его использовать. – Bronumski

+0

@bronumski, если производительность была ключевой целью, я бы использовал protobuf-net вместо :) –

0

К сожалению, 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 больше работы, но это, безусловно, лучшее решение в долгосрочной перспективе (не говоря уже о том, что это не хак).

2

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

Смежные вопросы