dynamic - Expression and delegate in c# -


i have below code pseudo-code. want make function can accept expresstion type, compile expression , invoke proper parameters.

public static void f<t>(expression<t> exp, params dynamic[] d) {     console.writeline("begin");     exp.compile().invoke(d[0],d[1].....);//this pseudo-code      console.writeline("end"); } 

i'm sure t action type. (t can action,action<int>,etc.). parameter d array of dynamic type, sent invoke.

but don't know how finish code. i'm sure that's not easy implement it. perhaps can't true in c#

you can't use invoke unless know exact signature. can, however, use dynamicinvoke, example:

((delegate)exp.compile()).dynamicinvoke(d); 

note dynamic in above serves no purpose - d object[].

the other, more complicated, approach - compile func<object[]>, , re-write expression (expressionvisitor) replace "parameter n" (from original exp) p[n], p single parameterexpression , n constantexpression of n. might advantageous if going store , aggressively re-use compiled lambda. in specific scenario compiling per call, have no benefit.

here's example, intended later readers similar scenarios, compiled delegate re-used; "advantage" of re-writing avoids performance impact of delegate.dynamicinvoke, while retaining object[] => object signature of delegate.dynamicinvoke; useful if delegate being used multiple times. @ moment (compiled per call) of "work" here going in expression-compile , jit-compile.

using system; using system.collections.generic; using system.linq.expressions; static class program {     static void main() {         expression<func<int, float, double>> exp = (i, f) => * f;         var func = compiletobasictype(exp);          object[] args = { 3, 2.3f };         object result = func(args); // 6.9 (double)     }      static func<object[], object> compiletobasictype(lambdaexpression exp) {         parameterexpression arg =             expression.parameter(typeof(object[]), "args");         dictionary<expression, expression> lookup =             new dictionary<expression, expression>();         int = 0;         foreach (var p in exp.parameters) {             lookup.add(p, expression.convert(expression.arrayindex(                 arg, expression.constant(i++)), p.type));         }         var body = expression.convert(             new replacevisitor(lookup).visit(exp.body), typeof(object));         return expression.lambda<func<object[], object>>(body, arg).compile();     }     class replacevisitor : expressionvisitor {         private readonly dictionary<expression, expression> lookup;         public replacevisitor(dictionary<expression, expression> lookup) {             if (lookup == null) throw new argumentnullexception("lookup");             this.lookup= lookup;         }         public override expression visit(expression node) {             expression found;             return lookup.trygetvalue(node, out found) ? found                 : base.visit(node);         }     } } 

Comments

Popular posts from this blog

blackberry 10 - how to add multiple markers on the google map just by url? -

php - guestbook returning database data to flash -

delphi - Dynamic file type icon -