代码之家  ›  专栏  ›  技术社区  ›  Patrik Svensson Martin Ender

使用DataContractSerializer时遇到问题

  •  2
  • Patrik Svensson Martin Ender  · 技术社区  · 14 年前

    我用DataContractSerializer序列化不可变实例时遇到问题,因为我序列化的类上的属性缺少setter。问题是,我只想序列化实例(只是为了将其写入日志),我会这样做 从未 需要反序列化它。有没有办法绕过这种行为?

    我尝试序列化的类:

    [DataContract]
    public class Person
    {
        private readonly string _name;
    
        [DataMember]
        public string Name
        {
            get { return _name; }
        }
    
        public Person(string name)
        {
            _name = name;
        }
    }
    

    用于序列化类的代码:

    public string Serialize()
    {
        var serializer = new DataContractSerializer(typeof(Person));
        StringBuilder stringBuilder = new StringBuilder();
        using (XmlWriter writer = XmlWriter.Create(stringBuilder)) {
            serializer.WriteObject(writer, this);
        }
        return stringBuilder.ToString();
    }
    
    2 回复  |  直到 14 年前
        1
  •  3
  •   aqwert    14 年前

    你可以把 [DataMember] 这样就可以有属性getter。这些字段仍然可以是私有的。但这不可能 readonly 因为它需要构造对象,然后设置字段。

    [编辑] 这将导致使用字段名,除非您使用 [DataMember(Name = "Name1")]

        2
  •  3
  •   MrFox    14 年前

    此版本使用ISerializable属性而不是[DataContract]。 我不知道这将如何影响可操作性,但不需要一个公共设置器。

    [Serializable]
    public class Person : ISerializable
    {
        private readonly string _name;
    
        public string Name
        {
            get { return _name; }
        }
    
        public Person(string name)
        {
            _name = name;
        }
    
        public string Serialize()
        {
            DataContractSerializer serializer = new DataContractSerializer(typeof(Person));
            System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder();
            using (System.Xml.XmlWriter writer = System.Xml.XmlWriter.Create(stringBuilder))
            {
                serializer.WriteObject(writer, this);
            }
            return stringBuilder.ToString();
        }
    
        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue("Name", _name);
        }
    }