Skip to content

Instantly share code, notes, and snippets.

@NickJosevski
Last active March 5, 2016 20:26
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save NickJosevski/956246019c431630931b to your computer and use it in GitHub Desktop.
Save NickJosevski/956246019c431630931b to your computer and use it in GitHub Desktop.
FSharpOptionConverter : JsonConverter
public class FSharpOptionConverter : JsonConverter
{
private static MethodInfo _getInnerValue = typeof (FSharpOptionConverter).GetMethod("GetInnerValue",
BindingFlags.Instance |
BindingFlags.NonPublic);
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value != null)
{
var optionValueType = value.GetType().GetGenericArguments().Single();
var method = _getInnerValue.MakeGenericMethod(new[] {optionValueType});
var innerValue = method.Invoke(this, new[]{value});
serializer.Serialize(writer, innerValue);
}
else
{
serializer.Serialize(writer, null);
}
}
private object GetInnerValue<T>(FSharpOption<T> option)
{
if (FSharpOption<T>.get_IsNone(option))
{
return null;
}
else
{
return option.Value;
}
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var optionValueType = objectType.GetGenericArguments().Single();
var makeGenericType = typeof (FSharpOption<>).MakeGenericType(new Type[] {optionValueType});
if (reader.TokenType == JsonToken.Null)
{
return MakeNone(makeGenericType);
}
var value = serializer.Deserialize(reader, optionValueType);
if (value == null)
{
return MakeNone(makeGenericType);
}
else
{
var someMethodInfo = makeGenericType.GetMethod("Some", BindingFlags.Static | BindingFlags.Public);
return someMethodInfo.Invoke(null, new[] {value});
}
}
private static object MakeNone(Type makeGenericType)
{
return makeGenericType
.GetProperty("None")
.GetGetMethod()
.Invoke(null, new object[0]);
}
public override bool CanConvert(Type objectType)
{
return objectType.IsGenericType && objectType.GetGenericTypeDefinition() == typeof(FSharpOption<>);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment