ili*_*ian 8 c# caching expression
我有一个用于检查方法参数的类,您可以在表单中调用它:
public void SomeMethod(string anArg)
{
Ensure.ArgumentNotNull(() => anArg);
}
Run Code Online (Sandbox Code Playgroud)
如果参数为null,则ArgumentNullException抛出具有该属性名称的参数.这样做是这样的:
public static void ArgumentNotNull<T>(Expression<Func<T>> expression) where T : class
{
var value = expression.Compile()();
if (value == null)
{
throw new ArgumentNullException(expression.GetMemberName());
}
}
Run Code Online (Sandbox Code Playgroud)
GetMemberName我写的扩展方法在哪里.
我遇到的问题是对Compile的调用非常慢,所以我想缓存结果,但我似乎无法想出一个足够独特的缓存密钥以防止缓存冲突,但不是那么独特,缓存变得无效.
到目前为止,我的最大努力是:
internal static class ExpressionCache<T>
{
private static readonly Dictionary<string, Func<T>> Cache = new Dictionary<string, Func<T>>();
public static Func<T> CachedCompile(Expression<Func<T>> targetSelector)
{
Func<T> cachedFunc;
var cacheKey = targetSelector + targetSelector.Body.ToString();
if (!Cache.TryGetValue(cacheKey, out cachedFunc))
{
cachedFunc = targetSelector.Compile();
Cache[cacheKey] = cachedFunc;
}
return cachedFunc;
}
}
Run Code Online (Sandbox Code Playgroud)
但这仍然会导致缓存密钥冲突.什么是更好的方法?
这些表达从何而来,它们是新创造的吗?如果重复使用它们,您可以使用表达式本身作为键:
internal static class ExpressionCache<T>
{
private static readonly Dictionary<Expression<Func<T>, Func<T>> Cache = new Dictionary<Expression<Func<T>, Func<T>>();
public static Func<T> CachedCompile(Expression<Func<T>> targetSelector)
{
Func<T> cachedFunc;
if (!Cache.TryGetValue(targetSelector, out cachedFunc))
{
cachedFunc = targetSelector.Compile();
Cache[targetSelector] = cachedFunc;
}
return cachedFunc;
}
}
Run Code Online (Sandbox Code Playgroud)
否则你可以窥探 DLR http://dlr.codeplex.com/的源代码,我相信他们很好地解决了这类问题。
| 归档时间: |
|
| 查看次数: |
2525 次 |
| 最近记录: |