在.Net 4.5项目中,我使用一种简单的实用工具方法以线程安全的方式记忆结果(实际上是一个Web应用程序):
public static class FuncUtilities
{
public static Func<TArg, TResult> ThreadsafeMemoize<TArg, TResult>(Func<TArg, TResult> f)
{
var cache = new ConcurrentDictionary<TArg, TResult>();
return arg => cache.GetOrAdd(arg, f);
}
public static Func<TArg, TArg2, TResult> ThreadsafeMemoize<TArg, TArg2, TResult>(Func<TArg, TArg2, TResult> f)
{
var cache = new ConcurrentDictionary<Tuple<TArg, TArg2>, TResult>();
return (arg, arg2) =>
{
var key = new Tuple<TArg, TArg2>(arg, arg2);
return cache.GetOrAdd(key, f(arg, arg2));
};
}
public static Func<TArg, TArg2, TArg3, TResult> ThreadsafeMemoize<TArg, TArg2, TArg3, TResult>(Func<TArg, TArg2, TArg3, TResult> f)
{
var cache = new ConcurrentDictionary<Tuple<TArg, TArg2, TArg3>, TResult>();
return (arg, arg2, arg3) =>
{
var key = new Tuple<TArg, TArg2, TArg3>(arg, arg2, arg3);
return cache.GetOrAdd(key, f(arg, arg2, arg3));
};
}
}
在另一个项目中,必须以3.5运行,我有相同的记忆结果的要求。
如何将我的代码移植到.Net 3.5?
我found partial port of the class,但它缺少GetOrAdd
方法,所以我尝试自己实现它:
public class ConcurrentDictionary<TKey, TValue>
{
private readonly object _Padlock = new object();
private readonly Dictionary<TKey, TValue> _Dictionary = new Dictionary<TKey, TValue>();
public TValue this[TKey key]
{
get { lock (_Padlock) { return _Dictionary[key]; } }
set { lock (_Padlock) { _Dictionary[key] = value; } }
}
public bool TryGetValue(TKey key, out TValue value)
{
lock (_Padlock)
{
return _Dictionary.TryGetValue(key, out value);
}
}
public TValue GetOrAdd(TKey key, Func<TKey, TValue> factory)
{
lock (_Padlock)
{
if (!_Dictionary.ContainsKey(key))
{
_Dictionary.Add(key, factory(key));
}
return _Dictionary[key];
}
}
}
我还必须&#34;模拟&#34;嵌套Tuple
KeyValuePair
课程
public static class FuncUtilities
{
public static Func<TArg, TResult> ThreadsafeMemoize<TArg, TResult>(Func<TArg, TResult> f)
{
var cache = new ConcurrentDictionary<TArg, TResult>();
return arg => cache.GetOrAdd(arg, f);
}
public static Func<TArg, TArg2, TResult> ThreadsafeMemoize<TArg, TArg2, TResult>(Func<TArg, TArg2, TResult> f)
{
var cache = new ConcurrentDictionary<KeyValuePair<TArg, TArg2>, TResult>();
return (arg, arg2) =>
{
var key = new KeyValuePair<TArg, TArg2>(arg, arg2);
return cache.GetOrAdd(key, f(arg, arg2));
};
}
public static Func<TArg, TArg2, TArg3, TResult> ThreadsafeMemoize<TArg, TArg2, TArg3, TResult>(Func<TArg, TArg2, TArg3, TResult> f)
{
var cache = new ConcurrentDictionary<KeyValuePair<KeyValuePair<TArg, TArg2>, TArg3>, TResult>();
return (arg, arg2, arg3) =>
{
var key = new KeyValuePair<KeyValuePair<TArg, TArg2>, TArg3>(new KeyValuePair<TArg, TArg2>(arg, arg2), arg3);
return cache.GetOrAdd(key, f(arg, arg2, arg3));
};
}
}
不幸的是,这不会编译:
1&GT; C:\一些\ FuncUtilities.cs(29,24,29,57): 错误CS1502:最佳重载方法匹配 &#39; some.ConcurrentDictionary,TResult&GT; .GetOrAdd(System.Collections.Generic.KeyValuePair, System.Func,TResult&GT;)&#39; 有一些无效的论点 1 GT; C:\一些\ FuncUtilities.cs(29,44,29,56): 错误CS1503:参数2:无法转换为&#39; TResult&#39;至 &#39; System.Func,TResult&GT;&#39; 1 GT; C:\一些\ FuncUtilities.cs(39,24,39,63): 错误CS1502:最佳重载方法匹配 &#39; some.ConcurrentDictionary,TArg3&GT;,&TResult GT; .GetOrAdd(System.Collections.Generic.KeyValuePair,TArg3&gt;中 System.Func,TArg3&GT;,&TResult GT;)&#39; 有一些无效的论点 1 GT; C:\一些\ FuncUtilities.cs(39,44,39,62): 错误CS1503:参数2:无法转换为&#39; TResult&#39;至 &#39; System.Func,TArg3&GT;,&TResult GT;&#39;