代码之家  ›  专栏  ›  技术社区  ›  Ana Betts

是否对只读属性进行WCF DataContract序列化?

  •  14
  • Ana Betts  · 技术社区  · 15 年前

    每当我使用wcf时,我总是试图创建一些不可变的类,这些类最终会通过连接(即,在构造函数中设置的参数,属性是只读的)。但是,这妨碍了WCF序列化,后者要求所有属性都是公共的get/set(这是有意义的,因为它必须对它们进行反序列化)。

    即使在 this related post ,我看到他们的解决方案最终将所有内容公开,这违背了我良好的编程意识。有办法解决这个问题吗?我是否必须接受这个解决方案,或者像冰棒一样的不变性,并对此感到满意?

    我尝试的另一件事是这样的,在这里我将拥有一个所有内容的基类和一个使集合无用的派生类:

    /// <summary>
    /// This represents a discovered virtual-machine template that can be
    /// instantiated into a RunningVirtualMachine
    /// </summary>
    [DataContract]
    [XmlRoot("VMTemplate")]
    public class VirtualMachineTemplateBase
    {
        [DataMember]
        public virtual ulong SizeInBytes { get; set; }
    }
    
    /// <summary>
    /// This class is the real guts of VirtualMachineTemplate that we're hiding
    /// from the base class.
    /// </summary>
    [XmlInclude(typeof(VirtualMachineTemplateBase))]
    public class VirtualMachineTemplate : VirtualMachineTemplateBase, IXmlPicklable, IEnableLogger
    {
        ulong _SizeInBytes;
        public override ulong SizeInBytes {
            get { return _SizeInBytes; }
            set { }
        }
    }
    
    2 回复  |  直到 10 年前
        1
  •  15
  •   pete the pagan-gerbil    10 年前

    如果使用DataContractSerializer(这是wcf的默认值),则可以序列化用 [DataMember] 属性-甚至是只读字段:

    [DataContract]
    public class VirtualMachineTemplate : VirtualMachineTemplateBase, IXmlPicklable, IEnableLogger
    {
        [DataMember]
        ulong _SizeInBytes;
    }
    

    但您需要使用DataContractSerializer,而不是XML序列化程序。XML序列化程序只能序列化公共属性(除非您在其上放置[xmlignore],否则它将序列化公共属性)。

    DataContractSerializer不同:

    • 它不需要无参数的默认构造函数
    • 它将 只有 序列化显式标记的内容 [数据成员]
    • 但这可以是任何东西——一个领域,一个财产,以及任何可见性(私有,受保护,公共)
    • 它比XMLSerializer快一点,但是您不能很好地控制XML的形状—您只能在所包含的内容中获得发言权。

    看到这个 blog post 而这 blog post 更多提示和技巧。

    马克

        2
  •  3
  •   Erno    11 年前

    为了同时确保不可变和易于实现,请为属性添加一个私有的setter以提供反序列化服务。发动机罩下面经常发生这种情况,但它起作用。