使用.NET DataContractSerializer实例,我可以检查传递给其构造函数的Type吗?

时间:2016-05-18 16:04:33

标签: .net xmlserializer datacontractserializer

我特别询问DataContractSerializer,但这也与XmlSerializer

有关

这些序列化程序类型的构造函数将Type对象作为参数,并且每个序列化程序实例只能序列化此类型的对象。

有什么方法可以稍后检查这种类型吗?没有明显的get属性或方法可以做到这一点。

我最终试图在DataContractSerializer上创建一个扩展方法,以简化将对象作为XML序列化为内存中的字符串。

对于这种扩展方法,检查类型不是关键任务,但我认为这将允许更清晰的异常处理。如果不进行检查,则用户只会获得SerializationException而不是ArguemntException

public static string WriteObjectToString(this DataContractSerializer serializer, object obj) {
    if (serializer == null) 
        throw new ArgumentNullException(nameof(serializer));
    if (obj == null) 
        throw new ArgumentNullException(nameof(obj));

    //---------------------------
    //This statement will not compile:
    if (serializer.TypeToSerialize != obj.GetType()) 
        throw new ArgumentException("Invalid type.");
    //---------------------------

    using (var output = new StringWriter())
    using (var writer = new XmlTextWriter(output)) {
        serializer.WriteObject(writer, obj);
        return output.GetStringBuilder().ToString();
    }        
}

一个有点相关的问题:

是否有一个原因DataContractSerializer(在将泛型引入.NET后创建,与XmlSerializer不同)使用Type对象参数而不是泛型类型?使用像

这样的方法DataContractSerializer{T}会不会更简单
  • void WriteObject(Stream, T)
  • T ReadObject(Stream)

1 个答案:

答案 0 :(得分:1)

你的第一个假设是不正确的。当您在其构造函数中传入knownTypes时,DataContractSerializer可以序列化不同类型的对象。但是,生成的xml将使用第一个类型名称作为其根xml元素名称。

下面的示例代码应该有效:

DataContractSerializer serializer = new DataContractSerializer(typeof(Foo), new Type[] {typeof(Bar), });
Bar bar = new Bar();
serializer.WriteObject(stream, bar);

生成的XML将如下所示:

<Foo><Bar>...</Bar></Foo>

希望这些信息会改变您的设计,因为没有必要为每种类型创建一个DataContractSerializer对象。但它应该解释为什么泛型不与DataContractSerializer一起使用。