Tôi có một số hiệu ứng lạ khi cố chạy mã f # qua phản xạ.
Với loại sau đâyLỗi phản chiếu lạ trên kiểu được suy ra
type Box<'a, 'b> = Box of 'a * 'b
và chức năng này
//iToS :: Box<'a,'b> -> Box<string,'b>
let iToS (Box (i, v)) = Box ((sprintf "%A" i), v)
tôi có thể dễ dàng và chính xác chạy đoạn mã sau
let r01 = iToS (Box (1, 1))
Tuy nhiên tôi cần phải chạy chức năng này ở các cạnh sắc nét các ranh giới hệ thống của tôi và cách duy nhất để làm như vậy là giảm sử dụng phản chiếu.
Vì vậy, tôi đã tạo ra chức năng này nên có một chức năng như trên và một bản ghi của các loại nhất định và áp dụng nó.
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
Nếu bây giờ tôi chạy ứng dụng này như dưới đây.
let r10 = (convert<Box<string, int>> <@ iToS @>) (Box (1, 1))
tôi nhận được lỗi sau
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
Ai đang cố gắng để chuyển đổi một cái gì đó vào một Box<obj, obj>
và tại sao?
Any help is appreciated
PS: Một số làm rõ ;-)
a) đây là một cách rõ ràng một câu hỏi về việc sử dụng phản ánh trong bối cảnh của F #
b) yeah, tôi biết vấn đề thực sự của tôi có thể được giải quyết mà không cần suy nghĩ và tôi đã làm như vậy rồi. Nó làm tăng kích thước mã của tôi một cách dễ dàng 40%.
c) vâng, tôi biết sự phản chiếu là con chó chậm. Tôi sẵn sàng để giao dịch tốc độ (tôi không cần) cho mã sạch hơn.
Hi, cảm ơn cho câu trả lời - alas nó không hoạt động :-( 'cho phép chuyển đổi (f: Báo giá.Expr <'t -> 'a>) (v:' a): 't' sẽ không biên dịch trong khi' để chuyển đổi <'t, 'a> (f: Báo giá.Expr) (v: 'a):' t' bị lỗi giống như trước. Ngoài ra vấn đề lớn nhất là tôi không thể đặt các loại như các tham số chung như tôi không có sau đó (ít nhất là không phải ở phần này của programm) – robkuz
Tôi nghĩ rằng các loại là một thứ tự sai trong câu trả lời. Bạn có thể thử 'let convert (f: Quotations.Expr <'a -> 't>) (v:' a): 't ='? –
Cảm ơn! Tôi sẽ sửa lỗi này. – gsomix