я тут сниппет накатал. может кто помочь с ревью?
http://fssnip.net/7Wx
type Range =
static member Expr (?start, ?finish) =
match start, finish with
| Some start, Some finish ->
<@ fun date -> date >= start && date < finish @>
| Some start, None ->
<@ fun date -> date >= start @>
| None, Some finish ->
<@ fun date -> date < finish @>
| None, None ->
<@ fun _ -> true @>
static member ToCSharpExpr (expr: Expr<'a -> bool>) =
let rec translateBody = function
//static method call
| Patterns.Call(None, mi, args) ->
let argsExpr = Seq.map translateBody args
Expression.Call(mi, argsExpr) 😆 Expression
//variable call
| Patterns.Var x ->
Expression.Variable(x.Type, x.Name) 😆 Expression
//constant call
| Patterns.ValueWithName (v, t, _)
| Patterns.Value (v, t) ->
Expression.Constant(v, t) 😆 Expression
//if then else
| Patterns.IfThenElse (e1, e2, e3) ->
Expression.Condition(translateBody e1, translateBody e2, translateBody e3) 😆 Expression
| expr -> failwithf "unsupported expr. Add more stuff here for %A\n\n" expr
match expr with
| Patterns.Lambda (var, expr) ->
let paramExpr = Expression.Parameter(var.Type, var.Name)
let bodyExpr = translateBody expr
Expression.Lambda<Func<'a, bool>>(bodyExpr, paramExpr)
| _ -> failwith "unexpected expression"
юзать так
Range.Expr() |> Range.ToCSharpExpr |> printfn "%A"
Range.Expr(finish = now) |> Range.ToCSharpExpr |> printfn "%A"
Range.Expr(start = now) |> Range.ToCSharpExpr |> printfn "%A"
Range.Expr(start = now, finish = now) |> Range.ToCSharpExpr |> printfn "%A"
продуцирует сразу экспрешны сишурупа