jeudi 29 septembre 2022

How can I make this reflection code work for any specific case of a generic type?

I have some data coming from some system via a TcpClient.

The system is a kind of column store with it's own way of representing null values. The system supports null for any type including int, DateTime etc.

The TcpClient returns values like DateTime.MinValue in case of nulls. But the client also has a null checking utility.

I have put together some reflection code to generate types, which works fine as long as I don't have any option types. I want to adapt this code to map null values to Option<'t>.

So far, I have the following utility.

let checkNull (x:obj) =
    let elementType = x.GetType()
    let defType = typedefof<ValueOption<_>>;
    let genericType = defType.MakeGenericType elementType
    let optionCaseInfoSome, _ = FSharpValue.GetUnionFields(DateTime.Now |> ValueSome :> obj, genericType)
    let valueNone:ValueOption<DateTime> = ValueNone
    let optionCaseInfoNone, _ = FSharpValue.GetUnionFields(valueNone :> obj, genericType)
    if KdbConstants.IsNull x then
        FSharpValue.MakeUnion(optionCaseInfoNone, Array.empty)
    else
        FSharpValue.MakeUnion(optionCaseInfoSome, [|x|])

This will only work for Option<DateTime> values. How can I adapt this to work for any Option<t>`?

PS: I am aware that my utility is not efficient and much of the values can be pre-calculated, rather than being run each time the function is called. I will clean it up once I get it to work.





Aucun commentaire:

Enregistrer un commentaire