@@ -42,47 +42,42 @@ public int GetHashCode((Type, Type[]) obj)
4242 }
4343 }
4444
45- private const string invokeMethodName = "Invoke" ;
46-
47- private static readonly ConcurrentDictionary < ( Type , Type [ ] ) , ConstructorInfo > constructorInfoByTypes =
48- new ConcurrentDictionary < ( Type , Type [ ] ) , ConstructorInfo > ( new TypesEqualityComparer ( ) ) ;
45+ private const string InvokeMethodName = "Invoke" ;
4946
5047 private static readonly object EmitLock = new object ( ) ;
5148 private static readonly int NullableTypeMetadataToken = WellKnownTypes . NullableOfT . MetadataToken ;
52- private static readonly Module NullableTypeModule = WellKnownTypes . NullableOfT . Module ;
49+ private static readonly int ValueTuple1 = typeof ( ValueTuple < > ) . MetadataToken ;
50+ private static readonly int ValueTuple8 = typeof ( ValueTuple < , , , , , , , > ) . MetadataToken ;
51+ private static readonly Module SystemCoreLibModule = WellKnownTypes . NullableOfT . Module ;
5352 private static readonly Type CompilerGeneratedAttributeType = typeof ( CompilerGeneratedAttribute ) ;
5453 private static readonly string TypeHelperNamespace = typeof ( TypeHelper ) . Namespace ;
5554
56- private static readonly ConcurrentDictionary < Type , Type [ ] > OrderedInterfaces =
57- new ConcurrentDictionary < Type , Type [ ] > ( ) ;
55+ private static readonly ConcurrentDictionary < ( Type , Type [ ] ) , ConstructorInfo > ConstructorInfoByTypes =
56+ new ( new TypesEqualityComparer ( ) ) ;
57+
58+ private static readonly ConcurrentDictionary < Type , Type [ ] > OrderedInterfaces = new ( ) ;
59+
60+ private static readonly ConcurrentDictionary < Type , Type [ ] > OrderedCompatibles = new ( ) ;
61+
62+ private static readonly ConcurrentDictionary < Pair < Type , Type > , InterfaceMapping > interfaceMaps = new ( ) ;
5863
59- private static readonly ConcurrentDictionary < Type , Type [ ] > OrderedCompatibles =
60- new ConcurrentDictionary < Type , Type [ ] > ( ) ;
64+ private static readonly ConcurrentDictionary < ( MethodInfo , Type ) , MethodInfo > GenericMethodInstances1 = new ( ) ;
6165
62- private static readonly ConcurrentDictionary < Pair < Type , Type > , InterfaceMapping > interfaceMaps =
63- new ConcurrentDictionary < Pair < Type , Type > , InterfaceMapping > ( ) ;
66+ private static readonly ConcurrentDictionary < ( MethodInfo , Type , Type ) , MethodInfo > GenericMethodInstances2 = new ( ) ;
6467
65- private static readonly ConcurrentDictionary < ( MethodInfo , Type ) , MethodInfo > GenericMethodInstances1 =
66- new ConcurrentDictionary < ( MethodInfo , Type ) , MethodInfo > ( ) ;
68+ private static readonly ConcurrentDictionary < ( Type , Type ) , Type > GenericTypeInstances1 = new ( ) ;
69+
70+ private static readonly ConcurrentDictionary < ( Type , Type , Type ) , Type > GenericTypeInstances2 = new ( ) ;
6771
6872 private static readonly Func < ( MethodInfo genericDefinition , Type typeArgument ) , MethodInfo > GenericMethodFactory1 =
6973 key => key . genericDefinition . MakeGenericMethod ( key . typeArgument ) ;
7074
71- private static readonly ConcurrentDictionary < ( MethodInfo , Type , Type ) , MethodInfo > GenericMethodInstances2 =
72- new ConcurrentDictionary < ( MethodInfo , Type , Type ) , MethodInfo > ( ) ;
73-
7475 private static readonly Func < ( MethodInfo genericDefinition , Type typeArgument1 , Type typeArgument2 ) , MethodInfo > GenericMethodFactory2 =
7576 key => key . genericDefinition . MakeGenericMethod ( key . typeArgument1 , key . typeArgument2 ) ;
7677
77- private static readonly ConcurrentDictionary < ( Type , Type ) , Type > GenericTypeInstances1 =
78- new ConcurrentDictionary < ( Type , Type ) , Type > ( ) ;
79-
8078 private static readonly Func < ( Type genericDefinition , Type typeArgument ) , Type > GenericTypeFactory1 = key =>
8179 key . genericDefinition . MakeGenericType ( key . typeArgument ) ;
8280
83- private static readonly ConcurrentDictionary < ( Type , Type , Type ) , Type > GenericTypeInstances2 =
84- new ConcurrentDictionary < ( Type , Type , Type ) , Type > ( ) ;
85-
8681 private static readonly Func < ( Type genericDefinition , Type typeArgument1 , Type typeArgument2 ) , Type > GenericTypeFactory2 = key =>
8782 key . genericDefinition . MakeGenericType ( key . typeArgument1 , key . typeArgument2 ) ;
8883
@@ -646,7 +641,7 @@ public static ConstructorInfo GetConstructor(this Type type, object[] arguments)
646641 GetSingleConstructor ( type , arguments . Select ( a => a ? . GetType ( ) ) . ToArray ( ) ) ;
647642
648643 public static ConstructorInfo GetSingleConstructor ( this Type type , Type [ ] argumentTypes ) =>
649- constructorInfoByTypes . GetOrAdd ( ( type , argumentTypes ) , ConstructorExtractor ) ;
644+ ConstructorInfoByTypes . GetOrAdd ( ( type , argumentTypes ) , ConstructorExtractor ) ;
650645
651646 private static readonly Func < ( Type , Type [ ] ) , ConstructorInfo > ConstructorExtractor = t => {
652647 ( var type , var argumentTypes ) = t ;
@@ -899,7 +894,7 @@ private static string GetShortNameBase(this Type type)
899894 /// <returns><see langword="True"/> if type is nullable type;
900895 /// otherwise, <see langword="false"/>.</returns>
901896 public static bool IsNullable ( this Type type ) =>
902- ( type . MetadataToken ^ NullableTypeMetadataToken ) == 0 && ReferenceEquals ( type . Module , NullableTypeModule ) ;
897+ ( type . MetadataToken ^ NullableTypeMetadataToken ) == 0 && ReferenceEquals ( type . Module , SystemCoreLibModule ) ;
903898
904899 /// <summary>
905900 /// Indicates whether <typeparamref name="T"/> type is a <see cref="Nullable{T}"/> type.
@@ -931,7 +926,7 @@ public static bool IsNullable(this Type type) =>
931926 /// </summary>
932927 /// <param name="delegateType">Type of the delegate to get the "Invoke" method of.</param>
933928 /// <returns><see cref="MethodInfo"/> object describing the delegate "Invoke" method.</returns>
934- public static MethodInfo GetInvokeMethod ( this Type delegateType ) => delegateType . GetMethod ( invokeMethodName ) ;
929+ public static MethodInfo GetInvokeMethod ( this Type delegateType ) => delegateType . GetMethod ( InvokeMethodName ) ;
935930
936931
937932 /// <summary>
@@ -1167,6 +1162,20 @@ public static bool IsNumericType(this Type type)
11671162 }
11681163 }
11691164
1165+ /// <summary>
1166+ /// Determines whether <paramref name="type"/> is generic form of <see cref="ValueTuple"/>
1167+ /// </summary>
1168+ /// <param name="type"></param>
1169+ /// <returns></returns>
1170+ internal static bool IsValueTuple ( this Type type )
1171+ {
1172+ // this stands on the theory that tokens for all generic versions of ValueTuple
1173+ // go one after another.
1174+ var currentToken = type . MetadataToken ;
1175+ return ( ( currentToken >= ValueTuple1 ) && currentToken <= ValueTuple8 )
1176+ && ReferenceEquals ( type . Module , SystemCoreLibModule ) ;
1177+ }
1178+
11701179 #region Private \ internal methods
11711180
11721181 /// <summary>
0 commit comments