3

I am implementing a custom (and generic) Json.net serializer and hit a bump in the road that I could use some help on.

When the deserializer is mapping to a property that is an interface, how can I best determine what sort of object to construct to deserialize to to place into the interface property.

I have the following:

[JsonConverter(typeof(MyCustomSerializer<foo>))]
class foo 
{
    int Int1 { get; set; }
    IList<string> StringList {get; set; }
}

My serializer properly serializes this object, and but when it comes back in, and I try to map the json parts to to object, I have a JArray and an interface.

I am currently instantiating anything enumerable like List as

 theList = Activator.CreateInstance(property.PropertyType);

This works create to work with in the deserialization process, but when the property is IList, I get runtime complaints (obviously) about not being able to instantiate an interface.

So how would I know what type of concrete class to create in a case like this?

Thank you

Roger Joys
  • 320
  • 1
  • 3
  • 11

1 Answers1

2

You could create a dictionary that maps interfaces to whichever type you think should be the default ("default type for an interface" isn't a defined concept in the language):

var defaultTypeFor = new Dictionary<Type, Type>();
defaultTypeFor[typeof(IList<>)] = typeof(List<>);
...
var type = property.PropertyType;
if (type.IsInterface) {
    // TODO: Throw an exception if the type doesn't exist in the dictionary
    if (type.IsGenericType) {
        type = defaultTypeFor[property.PropertyType.GetGenericTypeDefinition()];
        type = type.MakeGenericType(property.PropertyType.GetGenericArguments());
    }
    else {
        type = defaultTypeFor[property.PropertyType];
    }
}
theList = Activator.CreateInstance(type);

(I haven't tried this code; let me know if you get problems with it.)

Aasmund Eldhuset
  • 37,289
  • 4
  • 68
  • 81