This is a follow-up of this post and that post.
I need to write a function which takes an object (obj
type) and a key (also an obj
type), and if the object happens to be a Map, that is any Map<'k,'v>
then extracts its keys and values.
The difficulty is that I cannot parametrize the function with generic types and that we cannot pattern-match objects on generic types.
I am not familiar with F# Reflection, but I found a way to get the Map's values, once I know its keys. With this example code :
module TestItem =
open System
open Microsoft.FSharp.Reflection
// some uninteresting types for this example, could be anything arbitrary
type Foo = {argF1 : string; argF2 : double; argF3 : bool[]}
type Bar = {argB1 : string; argB2 : double; argB3 : Foo[]}
// and their instances
let foo1 = {argF1 = "foo1"; argF2 = 1.0; argF3 = [| true |]}
let foo2 = {argF1 = "foo2"; argF2 = 2.0; argF3 = [| false |]}
let bar1 = {argB1 = "bar1"; argB2 = 10.0; argB3 = [| foo1 |]}
let bar2 = {argB1 = "bar2"; argB2 = 20.0; argB3 = [| foo2 |]}
// a Map type
type Baz = Map<String,Bar>
let baz : Baz = [| ("bar1", bar1); ("bar2", bar2) |] |> Map.ofArray
let item (oMap : obj) (key : obj) : unit =
let otype = oMap.GetType()
match otype.Name with
| "FSharpMap`2" ->
printfn " -Map object identified"
let prop = otype.GetProperty("Item")
try
let value = prop.GetValue(oMap, [| key |])
printfn " -Value associated to key:\n %s" (value.ToString())
with
| _ ->
printfn " -Key missing from oMap"
| _ ->
printfn " -Not a Map object"
[<EntryPoint>]
let main argv =
printfn "#test with correct key"
let test = item baz "bar1"
printfn "\n#test with incorrect key"
let test = item baz "bar1X"
Console.ReadKey() |> ignore
0 // return exit code 0
Running the code above ouputs the following to the Console :
#test with correct key
-Map object identified
-Value associated to key:
{argB1 = "bar1";
argB2 = 10.0;
argB3 = [|{argF1 = "foo1";
argF2 = 1.0;
argF3 = [|true|];}|];}
#test with incorrect key
-Map object identified
-Key missing from oMap
Now, to solve my problem, I would just need to find a way to extract the keys from the oMap object.
My question : how to complete the code below to return the oMap keys, of type obj[], if oMap is indeed a boxed Map object?
module CompleteThis =
open System
open Microsoft.FSharp.Reflection
let keys (oMap : obj) (key : obj) : obj[] =
let otype = oMap.GetType()
match otype.Name with
| "FSharpMap`2" ->
printfn " -Map object identified"
(* COMPLETE HERE *)
Array.empty // dummy
| _ ->
printfn " -Not a Map object"
Array.empty // return empty array
Aucun commentaire:
Enregistrer un commentaire