Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/259.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 缓存从表达式编译<;Func<;T>&燃气轮机;_C#_Caching_Expression - Fatal编程技术网

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());