2
\$\begingroup\$

I would like to be specific in parameter types or write something like this:

Test test = (Json<Test>)"{\"age\": 46}";

Where:

public class Test 
{
    public int Age { get; set; }
}

My helper is:

public struct Json<T> 
{
    public static implicit operator string(Json<T> json) => json.JObject.ToString();
    public static explicit operator Json<T>(string json) => new Json<T>(json);

    public static implicit operator T(Json<T> json) => json.JObject.ToObject<T>();
    public static implicit operator Json<T>(T obj) => new Json<T>(JObject.FromObject(obj));

    static readonly JObject Default = JObject.FromObject(new { });

    Json(string json) : this(JObject.Parse(json)) { } 
    Json(JObject jObject) : this() => _jObject = jObject ?? 
        throw new ArgumentNullException(nameof(jObject));

    JObject JObject => _jObject ?? Default;
    readonly JObject _jObject;
}
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

The missing part is a JsonConverter:

[JsonConverter(typeof(JsonTConverter))]
public struct Json<T> 
{

And:

public class JsonTConverter : JsonConverter
{
    public override bool CanConvert(Type objectType) =>
        objectType.IsConstructedGenericType &&
        objectType.GetGenericTypeDefinition() == typeof(Json<>);

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) =>
        Activator.CreateInstance(objectType, reader.Value);

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) =>
        writer.WriteValue(value.ToString());
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.