Ich habe einige seltsame Effekte, wenn ich f # -Code über Reflektion ausführen möchte.
folgenden TypsMerkwürdiger Reflexionsfehler beim abgeleiteten Typ
type Box<'a, 'b> = Box of 'a * 'b
und diese Funktion
//iToS :: Box<'a,'b> -> Box<string,'b>
let iToS (Box (i, v)) = Box ((sprintf "%A" i), v)
ich leicht und korrekt den folgenden Code ausführen kann
let r01 = iToS (Box (1, 1))
jedoch diese Funktion an den scharfen Kanten Ich muss laufen meiner Systemgrenzen und der einzige Weg dies zu tun ist, auf die Reflektion zurückzugreifen.
Also habe ich diese Funktion erstellt, die eine Funktion wie oben und eine Aufzeichnung des angegebenen Typs nehmen und anwenden soll.
let convert<'t> (f:Quotations.Expr) (v:'a) : 't =
let methi e =
let rec methi' e =
match e with
| Call (x, mi, y) -> mi
| Lambda (_, body) -> methi' body
| _ -> failwith <| sprintf "not a function %A" e
methi' e
let apply f v =
let m = methi f
m.Invoke(null, [|box v|])
apply f v :?> 't
Wenn ich das jetzt aber wie unten ausführe.
let r10 = (convert<Box<string, int>> <@ iToS @>) (Box (1, 1))
bekomme ich folgende Fehler
System.ArgumentException : Object of type 'Box`2[System.Int32,System.Int32]' cannot be converted to type 'Box`2[System.Object,System.Object]'.
at System.RuntimeType.CheckValue (System.Object value, System.Reflection.Binder binder, System.Globalization.CultureInfo culture, System.Reflection.BindingFlags invokeAttr) [0x0007d] in <8cd55ece525b4760b63de40980e005aa>:0
at System.Reflection.MonoMethod.ConvertValues (System.Reflection.Binder binder, System.Object[] args, System.Reflection.ParameterInfo[] pinfo, System.Globalization.CultureInfo culture, System.Reflection.BindingFlags invokeAttr) [0x0007f] in <8cd55ece525b4760b63de40980e005aa>:0
at System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00014] in <8cd55ece525b4760b63de40980e005aa>:0
at System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) [0x00000] in <8cd55ece525b4760b63de40980e005aa>:0
at convert[t] (Microsoft.FSharp.Quotations.FSharpExpr f, Box`2[a,b] v) [0x00006] in <5831a15618eafa12a745038356a13158>:0
at test convert() [0x000e6] in <5831a15618eafa12a745038356a13158>:0
at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&)
at System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00038] in <8cd55ece525b4760b63de40980e005aa>:0
Wer etwas in eine Box<obj, obj>
und warum zu konvertieren versucht? Einige Erläuterungen ;-)
a) dies ist ausdrücklich eine Frage über die Verwendung von Reflexion im Rahmen von F #
b) ja, ich weiß, dass mein eigentliches Problem gelöst werden könnte, ohne Reflexion:
Jede Hilfe
PS geschätzt und ich habe es schon getan. Es erhöht meine Code-Größe um 40% leicht.
c) Ja, ich weiß, Reflexion ist Hund langsam. Ich bin bereit, Geschwindigkeit (ich brauche nicht) für saubereren Code zu handeln.
Hallo, danke für die Antwort tun - leider funktioniert es nicht :-( 'lassen konvertieren (f: Notierungen.Expr <'t -> 'a>) (v:' a): 't' wird nicht einmal kompilieren, während 'lassenkonvertieren(f: Quotations.Expr) (v: 'a):' t 'erhält den gleichen Fehler wie zuvor. Zusätzlich ist das größte Problem, dass ich die Typen nicht als generische Parameter setzen kann, wie ich es dann nicht habe (zumindest nicht in diesem Teil des Programms) – robkuz
Ich denke, dass Typen in der falschen Reihenfolge in der Antwort sind. Könnten Sie versuchen, lassen Sie konvertieren (f: Zitate.Expr <'a -> 't>) (v:' a): 't = '? –
Danke! Ich werde diesen Tippfehler beheben. – gsomix