I have a dictionary Dictionary. Both the outer dictionary and the inner one have an equality comparer set(in my
It would be better to create a converter that would create the dictionary objects as needed. This is precisely what the Newtonsoft.Json.Converters.CustomCreationConverter was designed for.
Here's one implementation that could create dictionaries that requires custom comparers.
public class CustomComparerDictionaryCreationConverter : CustomCreationConverter
{
private IEqualityComparer comparer;
public CustomComparerDictionaryCreationConverter(IEqualityComparer comparer)
{
if (comparer == null)
throw new ArgumentNullException("comparer");
this.comparer = comparer;
}
public override bool CanConvert(Type objectType)
{
return HasCompatibleInterface(objectType)
&& HasCompatibleConstructor(objectType);
}
private static bool HasCompatibleInterface(Type objectType)
{
return objectType.GetInterfaces()
.Where(i => HasGenericTypeDefinition(i, typeof(IDictionary<,>)))
.Where(i => typeof(T).IsAssignableFrom(i.GetGenericArguments().First()))
.Any();
}
private static bool HasGenericTypeDefinition(Type objectType, Type typeDefinition)
{
return objectType.IsGenericType && objectType.GetGenericTypeDefinition() == typeDefinition;
}
private static bool HasCompatibleConstructor(Type objectType)
{
return objectType.GetConstructor(new Type[] { typeof(IEqualityComparer) }) != null;
}
public override IDictionary Create(Type objectType)
{
return Activator.CreateInstance(objectType, comparer) as IDictionary;
}
}
Do note however that this converter will apply to all dictionary types where the key is covariant with T, regardless of value type.
Then to use it:
var converters = new JsonConverter[]
{
new CustomComparerDictionaryCreationConverter(StringComparer.OrdinalIgnoreCase),
};
var dict = JsonConvert.DeserializeObject>>(jsonString, converters);