public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { var token = JToken.Load(reader); var paramType = objectType.GenericTypeArguments[0]; // handle tuples // handle objects with Probability property (by structural matching) (including wrapper on tuple) if (ValueTupleReflectionHelper.IsValueTupleOrNullableType(paramType) || paramType.GetProperty(nameof(IProbabilityObject.Probability)) != null) { if (token is JArray jArray) { Type arType; if (paramType.GetInterface(nameof(IProbabilityObject)) != null) { arType = paramType.MakeArrayType(); } else { arType = typeof(ProbabilityObjectWrapper <>).MakeGenericType(paramType).MakeArrayType(); } var wrapperType = typeof(ProbabilityObjectCollection <>).MakeGenericType(paramType); var parsedArray = jArray.ToObject(arType, serializer); var wrapper = Activator.CreateInstance(wrapperType, parsedArray); return(wrapperType.GetProperty(nameof(ProbabilityObjectCollection <IProbabilityObject> .ProbabilityCollection)).GetValue(wrapper)); } } if (token.Type == JTokenType.Null) { return(null); } //other (simple) cases switch (token) { case JObject jObject: { var dictType = typeof(IDictionary <,>).MakeGenericType(paramType, typeof(decimal?)); return(Activator.CreateInstance(objectType, jObject.ToObject(dictType, serializer))); } case JArray jArray: { var arType = typeof(IList <>).MakeGenericType(paramType); return(Activator.CreateInstance(objectType, jArray.ToObject(arType, serializer))); } default: throw new InvalidOperationException("Invalid JToken type."); } }
public override bool CanConvert(Type objectType) => ValueTupleReflectionHelper.IsValueTupleOrNullableType(objectType, out var _, out var _);