The default serializer implementation (Serializer
) uses a Dictionary<Type, ISerializer>
to check for specialized serializers for specific types. The way a serializer is found (for a given Type
type
) is as follows:
Serializer
checks if Specialized
contains the type
as a key. If found, that is returned.
- If not found,
Serializer
searches for first Type that is exactly the generic type type
. If found, that is returned.
- If not found,
Serializer
searches for the first Type that inherits/implements the generic type type
. If found, that is returned.
- If no match is found, no specialized serializer is returned.
A closer look will reveal that steps 2 and 3 can lead to a hard-to-track issue.
What happens if there are multiple Types that inherit/implement the specified Type? Say for example, the specified Type is typeof(List<>)
, and Specialized
contains both typeof(IEnumerable<>)
and typeof(ICollection<>)
as keys. List<T>
implements both of these, so which one is chosen?
A simple answer is that whichever is encounter first in the linear search is picked. But Dictionary<TKey, TValue>
is not guaranteed to preserve order, and therein lies the problem.
That could lead to multiple calls of this method with the same parameter leading to different results, even if Specialized
is not mutated in between.
The only proper solution to this would be to use an ordered version of Dictionary<TKey, TValue>
that preserves insertion order and allows insertion using indexes. A non-generic OrderedDictionary
is already available under System.Collections.Specialized
. A generic OrderedDictionary<TKey, TValue>
would be ideal.