Caching 对表达式调用Compile()<;T>;多次访问和缓存

Caching 对表达式调用Compile()<;T>;多次访问和缓存,caching,lambda,c#-3.0,compilation,expression-trees,Caching,Lambda,C# 3.0,Compilation,Expression Trees,我在MSDN上找不到有关此问题的任何信息 如果我们创建一个表达式并对其调用Compile(),CLR会缓存编译的结果,因此对同一表达式的Compile()的任何后续调用都不会有太大影响,因为CLR会从内存缓存返回以前编译的Func AFAIK lambda表达式是不可变的,因此内部缓存实际上是有意义的。不,它只是将委托返回到编译版本。表达式本身不受影响 Expression<Func<T>> expression = ...; Func<T> compiled

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

如果我们创建一个
表达式
并对其调用
Compile()
,CLR会缓存编译的结果,因此对同一表达式的
Compile()
的任何后续调用都不会有太大影响,因为CLR会从内存缓存返回以前编译的
Func


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

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

Expression<Func<T>> expression = ...;
Func<T> compiled = expression.Compile();
T value = compiled();
Expression=。。。;
Func compiled=expression.Compile();
T值=已编译();

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

Expression<Func<T>> expression = ...;
Func<T> compiled = expression.Compile();
T value = compiled();
Expression=。。。;
Func compiled=expression.Compile();
T值=已编译();

这里有一点以linqpad脚本形式出现的巫术。这将在弱表中缓存编译后的值

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();
    } 
}
void Main()
{
表达式=()=>“你好”;
expression.ExecuteWithCachedCompile().Dump();//ta da!
}
静态类CachedCompileExtension
{
私有静态只读条件weaktable props=new ConditionalWeakTable();
公共静态T ExecuteWithCachedCompile(此表达式键)
{ 
var func=(func)props.GetValue(key,(k)=>key.Compile());
返回func();
} 
}

这里有一点以linqpad脚本形式出现的巫术。这将在弱表中缓存编译后的值

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();
    } 
}
void Main()
{
表达式=()=>“你好”;
expression.ExecuteWithCachedCompile().Dump();//ta da!
}
静态类CachedCompileExtension
{
私有静态只读条件weaktable props=new ConditionalWeakTable();
公共静态T ExecuteWithCachedCompile(此表达式键)
{ 
var func=(func)props.GetValue(key,(k)=>key.Compile());
返回func();
} 
}

谢谢你,雪熊。我投票决定将我自己的问题作为一个重复的问题结束以前从未这样做过。:)谢谢你,雪熊。我投票决定将我自己的问题作为一个重复的问题结束以前从未这样做过。:)@Robert缓存对返回的委托的引用应该很容易。我知道我知道。唯一的问题是我必须创建一个单独的类,在这个类中我将保存表达式本身和编译的委托引用,因为我将多次使用它。他们两个。若编译的委托将被缓存,那个么我可以简单地使用
表达式
,并避免使用自定义类。从可维护性的角度来看,代码越少越好。@Robert缓存对返回委托的引用应该很容易。我知道我知道。唯一的问题是我必须创建一个单独的类,在这个类中我将保存表达式本身和编译的委托引用,因为我将多次使用它。他们两个。若编译的委托将被缓存,那个么我可以简单地使用
表达式
,并避免使用自定义类。从可维护性的角度来看,代码越少越好。