c# - Trying to implement ConcurrentDictionary.GetOrAdd in a 3.5 project -
in .net 4.5 project, use simple utility method memoize results in thread safe way (a web app actually):
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)); }; } }
in project, wich must run 3.5, have same requirement of memoizing results.
how port code .net 3.5?
i found partial port of class, lacks getoradd
method, tried implement myself:
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] { { 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]; } } }
i have "simulate" tuple
class nesting 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)); }; } }
unfortunately, not compiles:
1>c:\some\funcutilities.cs(29,24,29,57): error cs1502: best overloaded method match 'some.concurrentdictionary,tresult>.getoradd(system.collections.generic.keyvaluepair, system.func,tresult>)' has invalid arguments 1>c:\some\funcutilities.cs(29,44,29,56): error cs1503: argument 2: cannot convert 'tresult' 'system.func,tresult>' 1>c:\some\funcutilities.cs(39,24,39,63): error cs1502: best overloaded method match 'some.concurrentdictionary,targ3>,tresult>.getoradd(system.collections.generic.keyvaluepair,targ3>, system.func,targ3>,tresult>)' has invalid arguments 1>c:\some\funcutilities.cs(39,44,39,62): error cs1503: argument 2: cannot convert 'tresult' 'system.func,targ3>,tresult>'
Comments
Post a Comment