编译Expression 时,是否隐式缓存?

编译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<Func> 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; } 

在这个例子中,我有点担心如果我缓存已编译的表达式,它将使用arg1arg2的值,就像编译表达式时一样,而不是从堆栈中的适当位置检索这些值(即而不是获得当前值)。

没有; 我不相信它; 如果你想要它被缓存,你必须保持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; } 

即,创建表达式的数字参数,并在运行时传递它们的实际值 (而不是表达式中的常量)。

Lambda experssions不会自动缓存。 您需要为此实现自己的缓存/记忆算法。 检查相关的Stackoverflow问题:

是否可以缓存在lambda表达式中计算的值?

值得注意的是,lambda表达式在C#中是惰性求值的。