c# - 使用 DataContractSerializer 自定义序列化

标签 c# serialization datacontractserializer datacontract

我目前正在为我的数据集使用包装器类,以实现自定义序列化。我想使用 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);
    }
}

谢谢!

最佳答案

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 接口(interface)的基类型。

如果您遇到问题,是序列化问题还是反序列化问题,还是两者都有?

关于c# - 使用 DataContractSerializer 自定义序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3156312/

相关文章:

c# - 如何在 C# 中的 List<string> 上切换大小写

.net - 如何在 .NET 中序列化大对象? (内存不足异常)

c# - 具有使用 IoC 容器的重载方法

c# - 在 ASP.NET MVC 2 Web 应用程序中输出具有 JSON 关系的 LINQ to SQL 实体时出现循环引用错误

c++ - SFINAE 序列化共享指针失败

.net - WCF 错误 "Maximum number of items that can be serialized or deserialized in an object graph is ' 6553 6'"

c# - 使用 DataContractSerializer 序列化时删除已知类型的命名空间

c# - 使用 DataContractSerializer 序列化覆盖的属性

c# - 在 C# 中使用 linq 从列表中的每一行获取第 n 个单词

c# - 我正在使用 Clipboard.GetDataObject();但有时它不能像我需要的那样工作