当Expression
被编译,是由框架隐式缓存由此得到的代码?我正在考虑静态Regex
方法,其中框架隐式编译并缓存最后几个正则表达式.
如果没有缓存编译Expression
对象,您是否可以推荐一些最佳实践来保持编译时间,或者如果我手动缓存表达式,可能会导致问题的任何问题?
public MyResultType DoSomething(int arg1, int arg2) { var result = invokeHandler( (IDoSomethingHandler h) => h.DoSomething(arg1, arg2) ); return result; } private TResult invokeHandler(Expression > action) where T : class { // Here, I might want to check to see if action is already cached. var compiledAction = action.Compile(); var methodCallExpr = action as MethodCallExpression; // Here, I might want to store methodCallExpr in a cache somewhere. var handler = ServiceLocator.Current.GetInstance (); var result = compiledAction(handler); return result; }
在这个例子中,我有点担心如果我缓存编译的表达式,它将使用arg1
和编译表达式时的值arg2
,而不是从堆栈中的适当位置检索这些值(即而不是获得当前值).
没有; 我不相信它; 如果你想要它被缓存,你必须保持Delegate
引用(通常Func<...>
或Action<...>
).同样,如果要获得最佳性能,可以将其编译为参数化表达式,以便在调用它时发送不同的值.
在这种情况下,重新措辞会有所帮助:
public MyResultType DoSomething(int arg1, int arg2) { var result = invokeHandler( (IDoSomethingHandler h, int a1, int a2) => h.DoSomething(a1, a2), arg1, arg2); return result; } private TResult invokeHandler(Expression > action, int arg1, int arg2) where T : class { // Here, I might want to check to see if action is already cached. var compiledAction = action.Compile(); var methodCallExpr = action as MethodCallExpression; // Here, I might want to store methodCallExpr in a cache somewhere. var handler = ServiceLocator.Current.GetInstance (); var result = compiledAction(handler, arg1, arg2); return result; }
即,使表达式的数字参数,并在运行时传递实际的(而不是表达式中的常量).