I have a generic class which contains a public property which is a generic interface of the same type as the parent class. Example code below.
public interface IExample<T>
{
T Value { get; set; }
string Name { get; set; }
}
public class Example<T> : IExample<T>
{
public string Name { get; set; }
public T Value { get; set; }
}
public class Parent<T>
{
public string ParentName { get; set; }
public IExample<T> ExampleItem { get; set; }
}
public class MainClass
{
public Parent<int> IntParent { get; set; }
}
I am using JSON.net to serialize the MainClass
object which can contain many Parent<T>
objects. Parent<T>
can be any generic with no type constraints. However, I cannot seem to deserialize the resulting JSON in a generic fashion.
I attempted to create a JsonConverter
for the JSON.net deserializer, but I cannot find a way to apply it generically. Example JsonConverter
below.
public class InterfaceJsonConverter<TInterface, TImplementation> : JsonConverter where TImplementation : TInterface, new()
{
public override bool CanConvert(Type objectType)
{
return (typeof(TInterface) == objectType);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return serializer.Deserialize<TImplementation>(reader);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
serializer.Serialize(writer, value);
}
}
The above converter would allow an attribute to be placed on the ExampleItem
property of the Parent<T>
class like:
public class Parent<T>
{
public string ParentName { get; set; }
[JsonConverter(typeof(InterfaceJsonConverter<IExample<T>, Example<T>>))]
public IExample<T> ExampleItem { get; set; }
}
But c# does not let you have generic type references in attributes (because of the nature of attributes and reflection). The only solution I have come up with so far is to add a new InterfaceJsonConverter
for each expected type T manually to the serializer before calling the Deserialize()
method. However, this limits the possible types of Parent<T>
since each type needs to be added manually if it can be deserialized.
Is there any way to deserialize this in a generic way? Is there another approach I should be taking?