View difference between Paste ID: XtiZGY9X and kdSKLsSi
SHOW: | | - or go back to the newest paste.
1
class Program
2
    {
3
        // Can't do IDictionary<int, Func<T, String>> as T is not available here.
4
        private static readonly IDictionary<int, Object> _cache = new Dictionary<int, Object>();
5
6
        public static void SomeToStringCalls()
7
        {
8
            Console.WriteLine(ToString(i => (i + 1).ToString(), 1));
9
            Console.WriteLine(ToString(i => (i + 1).ToString(), 2));
10
            Console.WriteLine(ToString(i => (i + 2).ToString(), 3));
11
            Console.WriteLine(ToString(i => (i + 2).ToString(), 4));
12
        }
13
14
        private static int GetExpressionHash<T>(Expression<Func<T, string>> expression)
15
        {
16
            int hash = expression.Body.ToString().GetHashCode();
17
            // if you consider parameter unimportant - comment this line
18
            // using quite simple and error-prone hash function h = h * 31 + update
19
            // you might want to switch to md5 or sha in production
20
            expression.Parameters.ToList().ForEach(param => hash = hash * 31 + param.Name.GetHashCode());
21
            return hash;
22
        }
23
24
        private static string ToString<T>(Expression<Func<T, string>> expression, T input)
25
        {
26
            var cacheKey = GetExpressionHash(expression);
27
            if (!_cache.ContainsKey(cacheKey))
28
            {
29
                _cache[cacheKey] = expression.Compile();
30
                Console.WriteLine(String.Format("Compiling expression {0}", expression.ToString()));
31
            }
32
            var method = (Func<T, string>) _cache[cacheKey];
33
            return method.Invoke(input);
34
        }
35
36
        static void Main(string[] args)
37
        {
38
            SomeToStringCalls();
39
            Console.ReadLine();
40
        }
41
    }