我检索给定类型的TryParse
方法,如下所示:
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
现在的问题是如何在调用该方法时提供第二个参数,该方法将解析结果作为引用.mutable
变量[1]会导致‘type instantiation Engine a byref type’编译错误,而ref
变量[2]会在运行时导致类型不匹配(此处给出,例如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