|
15 | 15 | using System.Collections.Generic;
|
16 | 16 | using System.ComponentModel;
|
17 | 17 | using System.Linq;
|
| 18 | +using System.Linq.Expressions; |
18 | 19 | using System.Reflection;
|
19 | 20 | using System.Runtime.Serialization;
|
20 | 21 | using System.Threading;
|
@@ -1793,6 +1794,42 @@ public static Type GetCollectionType(this Type type)
|
1793 | 1794 | return type.ElementType() ?? type.GetTypeGenericArguments().FirstOrDefault();
|
1794 | 1795 | }
|
1795 | 1796 |
|
| 1797 | + static Dictionary<string, Type> GenericTypeCache = new Dictionary<string, Type>(); |
| 1798 | + |
| 1799 | + public static Type GetCachedGenericType(this Type type, Type[] argTypes) |
| 1800 | + { |
| 1801 | + if (!type.IsGenericTypeDefinition) |
| 1802 | + throw new ArgumentException(type.FullName + " is not a Generic Type Definition"); |
| 1803 | + |
| 1804 | + var sb = StringBuilderThreadStatic.Allocate() |
| 1805 | + .Append(type.FullName); |
| 1806 | + foreach (var argType in argTypes) |
| 1807 | + { |
| 1808 | + sb.Append('|') |
| 1809 | + .Append(argType.FullName); |
| 1810 | + } |
| 1811 | + |
| 1812 | + var key = StringBuilderThreadStatic.ReturnAndFree(sb); |
| 1813 | + |
| 1814 | + Type genericType; |
| 1815 | + if (GenericTypeCache.TryGetValue(key, out genericType)) |
| 1816 | + return genericType; |
| 1817 | + |
| 1818 | + genericType = type.MakeGenericType(argTypes); |
| 1819 | + |
| 1820 | + Dictionary<string, Type> snapshot, newCache; |
| 1821 | + do |
| 1822 | + { |
| 1823 | + snapshot = GenericTypeCache; |
| 1824 | + newCache = new Dictionary<string, Type>(GenericTypeCache); |
| 1825 | + newCache[key] = genericType; |
| 1826 | + |
| 1827 | + } while (!ReferenceEquals( |
| 1828 | + Interlocked.CompareExchange(ref GenericTypeCache, newCache, snapshot), snapshot)); |
| 1829 | + |
| 1830 | + return genericType; |
| 1831 | + } |
| 1832 | + |
1796 | 1833 | private static readonly ConcurrentDictionary<Type, ObjectDictionaryDefinition> toObjectMapCache =
|
1797 | 1834 | new ConcurrentDictionary<Type, ObjectDictionaryDefinition>();
|
1798 | 1835 |
|
@@ -1903,6 +1940,11 @@ public static object FromObjectDictionary(this Dictionary<string, object> values
|
1903 | 1940 | return to;
|
1904 | 1941 | }
|
1905 | 1942 |
|
| 1943 | + public static object FromObjectDictionary<T>(this Dictionary<string, object> values) |
| 1944 | + { |
| 1945 | + return values.FromObjectDictionary(typeof(T)); |
| 1946 | + } |
| 1947 | + |
1906 | 1948 | private static ObjectDictionaryDefinition CreateObjectDictionaryDefinition(Type type)
|
1907 | 1949 | {
|
1908 | 1950 | var def = new ObjectDictionaryDefinition
|
|
0 commit comments