我特别询问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)
答案 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一起使用。