Reputation: 8665
I'm specifically asking about DataContractSerializer
, but this is also relevant to XmlSerializer
The constructors for these serializer types take a Type
object as an argument, and each serializer instance can only serialize objects of this type.
Is there any way to later check this type? There are no obvious get
properties or methods that do this.
I am ultimately trying to create an extension method on DataContractSerializer
to simplify serializing objects as XML to in-memory strings.
For this extension method, checking the type isn't mission critical, but I think it would allow for clearer exception handling. If the check is left off the user will just get a SerializationException
rather than an 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();
}
}
A somewhat related question:
Is there a reason why DataContractSerializer
(which was created after generics were introduced to .NET, unlike XmlSerializer
) uses a Type
object parameter rather than a generic type? Wouldn't it be simpler to have a DataContractSerializer{T}
with methods like
void WriteObject(Stream, T)
T ReadObject(Stream)
Upvotes: 0
Views: 58
Reputation: 3163
Your first assumption is incorrect. DataContractSerializer can serialize different types of objects when you pass in knownTypes in its constructor. However, the resulting xml will use the first type name as its root xml element name.
The sample code below should work:
DataContractSerializer serializer = new DataContractSerializer(typeof(Foo), new Type[] {typeof(Bar), });
Bar bar = new Bar();
serializer.WriteObject(stream, bar);
The resulting XML will look like this:
<Foo><Bar>...</Bar></Foo>
Hope this information will change your design, because it is not necessary to create a DataContractSerializer object per type. But it should explain why generic is not used with DataContractSerializer.
Upvotes: 1