使用 .NET DataContractSerializer 实例,我可以检查传递到其构造函数中的类型吗?

With .NET DataContractSerializer instance, can I check the Type that was passed into its constructor?

我特意询问 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} 不是更简单吗

你的第一个假设是不正确的。 DataContractSerializer 在其构造函数中传入 knownTypes 时,可以序列化不同类型的对象。但是,生成的 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 一起使用。