I retrieve a TryParse
method for a given type like this:
open System.Reflection
let stringParser<'T> =
typeof<'T>.GetMember("TryParse")
|> Seq.cast<MethodBase>
|> Seq.choose (fun m ->
let parameterTypes =
m.GetParameters()
|> Array.map (fun p -> (p.ParameterType, p.Attributes))
if parameterTypes =
[| (typeof<string>, ParameterAttributes.None)
; (typeof<'T>.MakeByRefType(), ParameterAttributes.Out) |] then Some m
else None)
|> Seq.exactlyOne
The question now is how to provide the second parameter when invoking the method, which contains the parse result as a reference. A mutable
variable [1] leads to the 'type instantiation involves a byref type' compilation error, and a ref
variable [2] leads to a type mismatch during runtime (given here, e.g., for uint16):
let fromString<'T> (s: string) =
// [1]
//let mutable parseResult = Unchecked.defaultof<'T>
// Using '&parseResult' gives:
// A type instantiation involves a byref type. This is not permitted by the rules of Common IL
// [2]
//let parseResult = ref (Unchecked.defaultof<'T>)
// Using 'parseResult' produces a runtime exception:
// System.ArgumentException: Object of type 'Microsoft.FSharp.Core.FSharpRef`1[System.UInt16]' cannot be converted to type 'System.UInt16&'.
// How to declare parseResult to retrieve the method result?
let potentialResult = stringParser<'T>.Invoke(null, [|s; parseResult|])
match potentialResult with
| :? bool as boolResult ->
if boolResult then Some (parseResult)
else None
| _ -> None
Aucun commentaire:
Enregistrer un commentaire