使用DataContractSerializer进行自定义序列化

10

我目前正在使用包装类来对我的数据集进行自定义序列化。我想使用DataContractSerializer(更像是必须使用它),但仍然支持自定义序列化。问题是[DataContract][Serializable]属性似乎不太兼容...我该如何覆盖序列化并支持同时使用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);
    }
}

谢谢!

1个回答

13

DataContractAttribute和SerializableAttribute可以同时使用。这里的好处是,您不需要使用单独的串行器。 DataContractSerializer是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);
    }
}

输出: "Matt"

仅使用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);
    }
}

输出: "Matt"

输出: 0

DataContractSerializer在遇到带有DataContractAttribute的类型时,会使用该属性代替将序列化传递给其基础类型,后者处理SerializableAttribute和ISerializable接口。

如果你遇到问题,是与序列化有关,还是与反序列化有关,或者两者都有?


2
你的三个示例似乎都缺少函数签名行。 - dotNET

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接