多次调用Expression <t>上的Compile()并缓存</t>

时间:2011-03-07 12:37:27

标签: caching lambda c#-3.0 compilation expression-trees

我没有在MSDN上找到有关此问题的任何信息。

如果我们创建一个Expression<Func<T>>并在其上调用Compile(),CLR会缓存已编译的结果,因此Compile()对同一表达式的任何后续调用都不会产生太大影响,因为CLR会从内部内存缓存返回先前编译的Func<T>

AFAIK lambda表达式是不可变的,因此内部缓存实际上是有意义的。

2 个答案:

答案 0 :(得分:1)

不,它只是将一个委托返回到编译版本。表达本身不受影响。

Expression<Func<T>> expression = ...;
Func<T> compiled = expression.Compile();
T value = compiled();

答案 1 :(得分:0)

以linqpad脚本的形式出现了一些死灵法术。这会将编译后的值缓存在Weak表中

void Main()
{
    Expression<Func<string>> expression = () => "hello";
    expression.ExecuteWithCachedCompile().Dump(); //ta-da!
}
static class CachedCompileExtension
{
    private static readonly ConditionalWeakTable<object, object> props = new ConditionalWeakTable<object, object>();

    public static T ExecuteWithCachedCompile<T>(this Expression<Func<T>> key)
    { 
        var func = (Func<T>) props.GetValue(key, (k) => key.Compile());       
        return func();
    } 
}