As mentioned in the follow-up comment to the original question, .NET emits assemblies when creating XmlSerializers, and caches the generated assembly if it is created using one of these two constructors:
XmlSerializer(Type)
XmlSerializer(Type, String)
Assemblies generated using the other constructors are not cached, so .NET has to generate new assemblies every time.
Why? This answer probably isn't very satisfying, but peering at this in Reflector, you can see that the key used to store and access the generated XmlSerializer
assemblies (TempAssemblyCacheKey
) is just a simple composite key built from the serializable type and (optionally) its namespace.
Thus, there's no mechanism to tell whether a cached XmlSerializer
for SomeType
has a special XmlRootAttribute
or the default one.
It's hard to think of a technical reason that the key couldn't accommodate more elements, so this is probably just a feature that no none had time to implement (especially since it would involve changing otherwise stable classes).
You may have seen this, but in case you haven't, the XmlSerializer
class documentation discusses a workaround:
If you use any of the other
constructors, multiple versions of the
same assembly are generated and never
unloaded, which results in a memory
leak and poor performance. The easiest
solution is to use one of the
previously mentioned two constructors.
Otherwise, you must cache the
assemblies in a Hashtable,
as shown in
the following example.
(I've omitted the example here)