Advertisement
Guest User

Untitled

a guest
Jul 26th, 2016
60
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.87 KB | None | 0 0
  1. Reflection is useful but fragile. Consider this:
  2.  
  3. let mi = typeof<System.String>.GetMethod "StartsWith"
  4.  
  5. The problems with this kind of code are:
  6.  
  7. 1. The code doesn't work because there are several overloads of `String.StartsWith`
  8. 2. Even if there wouldn't be any overloads right now later versions of the library might add an overload causing a runtime crash
  9. 3. Refactoring tools like `Rename methods` is broken with reflection.
  10.  
  11. This means we get a runtime crashes for something that is known compile-time. That seems suboptimal.
  12.  
  13. Using `F#` quotations it's possible to avoid all the problems above. We define some helper functions:
  14.  
  15. open FSharp.Quotations
  16. open System.Reflection
  17.  
  18. let getConstructorInfo (e : Expr<'T>) : ConstructorInfo =
  19. match e with
  20. | Patterns.NewObject (ci, _) -> ci
  21. | _ -> failwithf "Expression has the wrong shape, expected NewObject (_, _) instead got: %A" e
  22.  
  23.  
  24. let getMethodInfo (e : Expr<'T>) : MethodInfo =
  25. match e with
  26. | Patterns.Call (_, mi, _) -> mi
  27. | _ -> failwithf "Expression has the wrong shape, expected Call (_, _, _) instead got: %A" e
  28.  
  29. We use the functions like this:
  30.  
  31. printfn "%A" <| getMethodInfo <@ "".StartsWith "" @>
  32. printfn "%A" <| getMethodInfo <@ List.singleton 1 @>
  33. printfn "%A" <| getConstructorInfo <@ System.String [||] @>
  34.  
  35. This prints:
  36.  
  37. Boolean StartsWith(System.String)
  38. Void .ctor(Char[])
  39. Microsoft.FSharp.Collections.FSharpList`1[System.Int32] Singleton[Int32](Int32)
  40.  
  41. `<@ ... @>` means that instead of executing the expression inside `F#` generates an expression tree representing the expression.
  42. `<@ "".StartsWith "" @>` generates an expression tree that looks like this: `Call (Some (Value ("")), StartsWith, [Value ("")])`.
  43. This expression tree matches what `getMethodInfo` expects and it will return the correct method info.
  44.  
  45. This resolves all the problems listed above.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement