2010-10-18 64 views
3

我有一个类与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抱怨它。

是否有一个属性或其他技术能够使变换值不可译,除了序列化程序?

另外如果没有选项,则将该属性设置为Obsolete是一个选项。是否还有其他更适合使用的属性?

回答

2

这是XmlSerializer的一种痛苦,用DataContractSerialzer(它也可以在没有XmlSerializer需要的无参数ctor的情况下)工作。只需将该类型标记为[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 2010-10-18 16:40:20

+0

@bronumski如果性能是关键目标,我会使用protobuf网而不是:) – 2010-10-18 18:04:22

0

不幸的是,XmlSerializer只能使用公共getters/setter序列化属性(除非你指定通过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,它将调用接口公开的对象上的方法。是的,它是更多的工作,但你有一个更好的粒度方法,你的对象是如何de /序列化。