Sen desen eşleştirme ile bir F # Kod Alıntılar değerlendirebilirsiniz:
open Microsoft.FSharp.Quotations.Patterns
let rec eval = function
| Value(v,t) -> v
| Call(None,mi,args) -> mi.Invoke(null, evalAll args)
| arg -> raise <| System.NotSupportedException(arg.ToString())
and evalAll args = [|for arg in args -> eval arg|]
let x = eval <@ 1 * 3 @>
F# PowerPack, Unquote, Foq ÖSS projeleri veya daha eksiksiz uygulamaları için bu snippet bakınız.
Reflection.Emit kullanarak bir F # Kod Teklifi yapabilirsiniz define a dynamic method derlemek için:
open System
open System.Reflection
let createAssembly quotation =
let name = "GeneratedAssembly"
let domain = AppDomain.CurrentDomain
let assembly = domain.DefineDynamicAssembly(AssemblyName(name), AssemblyBuilderAccess.RunAndSave)
let dm = assembly.DefineDynamicModule(name+".dll")
let t = dm.DefineType("Type", TypeAttributes.Public ||| TypeAttributes.Class)
let mb = t.DefineMethod("f", MethodAttributes.Public, typeof<int>, [||])
let il = mb.GetILGenerator()
quotation |> generate il
il.Emit(OpCodes.Ret)
assembly.Save("GeneratedAssembly.dll")
createAssembly <@ 1 + 1 @>
bakınız:
open System.Reflection.Emit
let rec generate (il:ILGenerator) = function
| Value(v,t) when t = typeof<int> ->
il.Emit(OpCodes.Ldc_I4, v :?> int)
| Call(None,mi,args) ->
generateAll il args
il.EmitCall(OpCodes.Call, mi, null)
| arg -> raise <| System.NotSupportedException(arg.ToString())
and generateAll il args = for arg in args do generate il arg
type Marker = interface end
let compile quotation =
let f = DynamicMethod("f", typeof<int>, [||], typeof<Marker>.Module)
let il = f.GetILGenerator()
quotation |> generate il
il.Emit(OpCodes.Ret)
fun() -> f.Invoke(null,[||]) :?> int
let f = compile <@ 1 + 3 @>
let x = f()
bir derlemeye derlemek için tekrar bir yöntemle bir tür oluşturmak için Reflection.Emit kullanmak Daha eksiksiz bir uygulama için Fil projesi (F # ila IL).
PowerPack'in bunu destekleyip desteklemediğinden emin değilim. Ama bir yana, PowerPack'i hiç kullanmamayı tavsiye etmem. Kodları genellikle buggy veya çok yavaştır. System.Reflection.Emit kullanarak kendi derleyicinizi veya değerlendiricinizi sıfırdan yazmak, muhtemelen daha iyi sonuçlar verecektir. Ayrıca F # 'nin teklifleri optimize etmemesi gibi bir problem de vardır, örneğin eşleme, normal F # derlemesinde CIL'de olduğu gibi atlama komutu yerine bir/sonra/else dizisi olur. – t0yv0
Merhaba, bunun için teşekkürler, sanırım onlara alternatifler bakacağım (Reflection.Emit sözünü ettiğin gibi). – Ncc
Bu yararlı bulabilirsiniz: http://stackoverflow.com/questions/2682475/converting-f-quotations-into-linq-expressions ve http://stackoverflow.com/questions/1618682/linking-a-net-expression Yeni bir proje başlatmak için -t-new-assembly- – JPW