【问题标题】:Custom serialization with DataContractSerializer使用 DataContractSerializer 自定义序列化
【发布时间】:2011-03-10 12:53:19
【问题描述】:

我目前正在为我的 DataSets 使用包装类,以实现自定义序列化。我想使用DataContractSerializer(更像是必须使用它)但仍然支持自定义序列化。问题是 [DataContract][Serializable] 属性似乎相处得不太好......我怎么能覆盖序列化,并支持 BOTH DataContract 和 ISerializable 序列化? 这里带来了包装DataSet类的代码:

[Serializable()]    
[System.Runtime.InteropServices.ComVisible(false)]
public class TestDatasetWrapper : TestDataSet, ISerializable
{
    public TestDatasetWrapper()
        : base()
    {}

    protected TestDatasetWrapper(SerializationInfo info, StreamingContext context)
    {
        SerializationHelper.DeserializeTypedDataSet(info, this);
    }

    public override void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        SerializationHelper.AddTypedDataSetObjectData(info, this);
    }
}

谢谢!

【问题讨论】:

    标签: c# serialization datacontractserializer datacontract


    【解决方案1】:

    DataContractAttribute 和 SerializableAttribute 可以一起使用。这里的好处是,您也不需要使用单独的序列化程序。 DataContractSerialzer 是一个 XmlObjectSerializer,它本身支持 [Serializable]。例如:

    [Serializable]
    public class TestClass
    {
        public string Name { get; set; }
    }
    
    {
        var formatter = new DataContractSerializer(typeof(TestClass));
        using (var stream = new MemoryStream())
        {
            var instance = new TestClass { Name = "Matt" };
            formatter.WriteObject(stream, instance);
    
            stream.Seek(0, SeekOrigin.Begin);
    
            var second = (TestClass) formatter.ReadObject(stream);
            Console.WriteLine(second.Name);
        }
    }
    

    输出:“马特”

    仅使用一个 SerializableAttribute 属性,我们就可以使用 DataContractSerializer 成功地序列化和反序列化对象...

    使用 ISerializable,我们可以做同样的事情:

    [Serializable]
    public class TestClass2 : ISerializable
    {
        public TestClass2() { }
        protected TestClass2(SerializationInfo info, StreamingContext context)
        {
            Name = info.GetString("name").ToUpper();
        }
    
        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue("name", Name);
        }
    
        public string Name { get; set; }
    }
    
    {
        var formatter = new DataContractSerializer(typeof(TestClass2));
        using (var stream = new MemoryStream())
        {
            var instance = new TestClass2 { Name = "Matt" };
            formatter.WriteObject(stream, instance);
    
            stream.Seek(0, SeekOrigin.Begin);
    
            var second = (TestClass2)formatter.ReadObject(stream);
            Console.WriteLine(second.Name);
        }
    }
    

    输出:“MATT”

    并带有 DataContractAttribute:

    [DataContract, Serializable]
    public class TestClass3
    {
        public int Age { get; set; }
    
        [DataMember]
        public string Name { get; set; }
    }
    
    {
        var formatter = new DataContractSerializer(typeof(TestClass3));
        using (var stream = new MemoryStream())
        {
            var instance = new TestClass3 { Name = "Matt", Age = 26 };
            formatter.WriteObject(stream, instance);
    
            stream.Seek(0, SeekOrigin.Begin);
    
            var second = (TestClass3)formatter.ReadObject(stream);
            Console.WriteLine(second.Name);
            Console.WriteLine(second.Age);
        }
    }
    

    输出:“马特”

    输出:0

    当 DataContractSerializer 遇到具有 DataContractAttribute 的类型时,它将使用该类型而不是将序列化传递给其处理 SerializableAttribute 和 ISerializable 接口的基类型。

    如果您遇到问题,是与序列化有关,还是与反序列化有关,或两者兼而有之?

    【讨论】:

    • 您的所有 3 个样本似乎都缺少函数签名行。
    猜你喜欢
    • 2019-01-25
    • 1970-01-01
    • 1970-01-01
    • 2013-03-03
    • 1970-01-01
    • 2010-12-30
    • 1970-01-01
    • 2021-02-13
    相关资源
    最近更新 更多