C# 缓存从表达式编译<;Func<;T>&燃气轮机;
我有一个用于检查方法参数的类,您以以下形式调用该类:C# 缓存从表达式编译<;Func<;T>&燃气轮机;,c#,caching,expression,C#,Caching,Expression,我有一个用于检查方法参数的类,您以以下形式调用该类: public void SomeMethod(string anArg) { Ensure.ArgumentNotNull(() => anArg); } 如果参数为null,则会抛出一个带有属性名称的ArgumentNullException。这是这样做的: public static void ArgumentNotNull<T>(Expression<Func<T>> expressi
public void SomeMethod(string anArg)
{
Ensure.ArgumentNotNull(() => anArg);
}
如果参数为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());
}
}
但这仍然会导致缓存密钥冲突。有什么更好的方法吗?在这个主题上有,不幸的是它们是用中文写的。一个好消息是,您可以下载ExpressionTree缓存的完整实现代码。就我个人而言,我还有另一个建议:为什么不呢?这些经验是从哪里来的,它们是新产生的吗?如果重复使用它们,则可以将表达式本身用作键:
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;
}
}
内部静态类ExpressionCache
{
私有静态只读字典而不是使用<代码>字典<代码>,如果你更关心种族条件和可读性而不是性能(我不确定它是否会是最坏的),你可以考虑使用<代码>并发字典< /C>
它已经有了一个GetOrAdd
方法,可以让您编写更少的代码,而且随着.NET4.0的推出,它可以确保工作正常,并且有很好的文档记录
var dict = new ConcurrentDictionary<Expression<Func<T>, Func<T>>();
...
var cacheKey = targetSelector; //or whatever as long as it's unique
var cachedFunc = dict.GetOrAdd(cacheKey, key => targetSelector.Compile());
var dict=new concurrentdictories我会使用PostSharp或IL:@Ruben,你说得对,我在发布之前对浏览器进行了一些黑客攻击。我会更正它。我可以问一下,为什么需要将它作为表达式输入参数检查器…为什么不只是值?只是为了能够抛出该异常?你能提供两个表达式的示例吗锡安:那会有冲突吗?下载链接坏了,你碰巧没有它,也不知道它是否可以在其他地方找到?(我找不到它,不幸的是文件本身无法从archive.org中检索。)@HåkanLindqvist:对不起,msdn链接已失效,我没有源代码。恐怕你需要阅读中文写的博客(在谷歌翻译的帮助下?),文章中有一些代码片段。
var dict = new ConcurrentDictionary<Expression<Func<T>, Func<T>>();
...
var cacheKey = targetSelector; //or whatever as long as it's unique
var cachedFunc = dict.GetOrAdd(cacheKey, key => targetSelector.Compile());