@@ -47,17 +47,18 @@ public int GetHashCode((Type, Type[]) obj)
47
47
48
48
private static readonly object EmitLock = new object ( ) ;
49
49
private static readonly int NullableTypeMetadataToken = WellKnownTypes . NullableOfT . MetadataToken ;
50
- private static readonly int ValueTuple1 = typeof ( ValueTuple < > ) . MetadataToken ;
51
- private static readonly int ValueTuple8 = typeof ( ValueTuple < , , , , , , , > ) . MetadataToken ;
50
+ private static readonly int ValueTuple1MetadataToken = typeof ( ValueTuple < > ) . MetadataToken ;
51
+ private static readonly int ValueTuple8MetadataToken = typeof ( ValueTuple < , , , , , , , > ) . MetadataToken ;
52
52
private static readonly Module SystemCoreLibModule = WellKnownTypes . NullableOfT . Module ;
53
53
private static readonly Type CompilerGeneratedAttributeType = typeof ( CompilerGeneratedAttribute ) ;
54
54
private static readonly string TypeHelperNamespace = typeof ( TypeHelper ) . Namespace ;
55
55
56
+ #region Caches and cache items factories
56
57
#if NET8_0_OR_GREATER
57
58
private static readonly ConcurrentDictionary < ( Type , Type [ ] ) , ConstructorInvoker > ConstructorInvokerByTypes =
58
- #else
59
- private static readonly ConcurrentDictionary < ( Type , Type [ ] ) , ConstructorInfo > ConstructorInfoByTypes =
59
+ new ( new TypesEqualityComparer ( ) ) ;
60
60
#endif
61
+ private static readonly ConcurrentDictionary < ( Type , Type [ ] ) , ConstructorInfo > ConstructorInfoByTypes =
61
62
new ( new TypesEqualityComparer ( ) ) ;
62
63
63
64
private static readonly ConcurrentDictionary < Type , Type [ ] > OrderedInterfaces = new ( ) ;
@@ -71,16 +72,11 @@ public int GetHashCode((Type, Type[]) obj)
71
72
private static readonly ConcurrentDictionary < ( MethodInfo , Type ) , MethodInfo > GenericMethodInstances1 = new ( ) ;
72
73
73
74
private static readonly ConcurrentDictionary < ( MethodInfo , Type , Type ) , MethodInfo > GenericMethodInstances2 = new ( ) ;
74
-
75
75
#if NET8_0_OR_GREATER
76
- private static readonly ConcurrentDictionary< ( MethodInfo , Type ) , MethodInvoker > GenericMethodInvokers1 = new ( ) ;
77
- private static readonly ConcurrentDictionary < ( MethodInfo , Type , Type ) , MethodInvoker > GenericMethodInvokers2 = new ( ) ;
78
76
79
- private static readonly Func < ( MethodInfo genericDefinition , Type typeArgument ) , MethodInvoker > GenericMethodInvokerFactory1 =
80
- key => MethodInvoker . Create ( key . genericDefinition . MakeGenericMethod ( key . typeArgument ) ) ;
77
+ private static readonly ConcurrentDictionary < ( MethodInfo , Type ) , MethodInvoker > GenericMethodInvokers1 = new ( ) ;
81
78
82
- private static readonly Func < ( MethodInfo genericDefinition , Type typeArgument1 , Type typeArgument2 ) , MethodInvoker > GenericMethodInvokerFactory2 =
83
- key => MethodInvoker . Create ( key . genericDefinition . MakeGenericMethod ( key . typeArgument1 , key . typeArgument2 ) ) ;
79
+ private static readonly ConcurrentDictionary < ( MethodInfo , Type , Type ) , MethodInvoker > GenericMethodInvokers2 = new ( ) ;
84
80
#endif
85
81
86
82
private static readonly ConcurrentDictionary < ( Type , Type ) , Type > GenericTypeInstances1 = new ( ) ;
@@ -93,11 +89,21 @@ public int GetHashCode((Type, Type[]) obj)
93
89
private static readonly Func < ( MethodInfo genericDefinition , Type typeArgument1 , Type typeArgument2 ) , MethodInfo > GenericMethodFactory2 =
94
90
key => key . genericDefinition . MakeGenericMethod ( key . typeArgument1 , key . typeArgument2 ) ;
95
91
96
- private static readonly Func < ( Type genericDefinition , Type typeArgument ) , Type > GenericTypeFactory1 = key =>
97
- key . genericDefinition . MakeGenericType ( key . typeArgument ) ;
92
+ private static readonly Func < ( Type genericDefinition , Type typeArgument ) , Type > GenericTypeFactory1 =
93
+ key => key . genericDefinition . MakeGenericType ( key . typeArgument ) ;
94
+
95
+ private static readonly Func < ( Type genericDefinition , Type typeArgument1 , Type typeArgument2 ) , Type > GenericTypeFactory2 =
96
+ key => key . genericDefinition . MakeGenericType ( key . typeArgument1 , key . typeArgument2 ) ;
97
+ #if NET8_0_OR_GREATER
98
+
99
+ private static readonly Func < ( MethodInfo genericDefinition , Type typeArgument ) , MethodInvoker > GenericMethodInvokerFactory1 =
100
+ key => MethodInvoker . Create ( key . genericDefinition . MakeGenericMethod ( key . typeArgument ) ) ;
101
+
102
+ private static readonly Func < ( MethodInfo genericDefinition , Type typeArgument1 , Type typeArgument2 ) , MethodInvoker > GenericMethodInvokerFactory2 =
103
+ key => MethodInvoker . Create ( key . genericDefinition . MakeGenericMethod ( key . typeArgument1 , key . typeArgument2 ) ) ;
104
+ #endif
98
105
99
- private static readonly Func < ( Type genericDefinition , Type typeArgument1 , Type typeArgument2 ) , Type > GenericTypeFactory2 = key =>
100
- key . genericDefinition . MakeGenericType ( key . typeArgument1 , key . typeArgument2 ) ;
106
+ #endregion
101
107
102
108
private static int createDummyTypeNumber = 0 ;
103
109
private static AssemblyBuilder assemblyBuilder ;
@@ -645,34 +651,50 @@ public static object Activate(this Type type, Type[] genericArguments, params ob
645
651
}
646
652
}
647
653
654
+ #if NET8_0_OR_GREATER
648
655
/// <summary>
649
- /// Gets the public constructor of type <paramref name="type"/>
656
+ /// Gets <see cref="ConstructorInvoker"/> of the public constructor of type <paramref name="type"/>
650
657
/// accepting specified <paramref name="argumentTypes"/>.
651
658
/// </summary>
652
659
/// <param name="type">The type to get the constructor for.</param>
653
660
/// <param name="argumentTypes">The arguments.</param>
654
661
/// <returns>
655
- /// Appropriate constructor, if a single match is found;
662
+ /// Appropriate constructor invoker , if a single match is found;
656
663
/// otherwise throws <see cref="InvalidOperationException"/>.
657
664
/// </returns>
658
665
/// <exception cref="InvalidOperationException">
659
666
/// The <paramref name="type"/> has no constructors suitable for <paramref name="argumentTypes"/>
660
667
/// -or- more than one such constructor.
661
668
/// </exception>
662
- #if NET8_0_OR_GREATER
663
- public static ConstructorInvoker GetSingleConstructorInvoker ( this Type type , Type [ ] argumentTypes ) =>
669
+ internal static ConstructorInvoker GetSingleConstructorInvoker ( this Type type , Type [ ] argumentTypes ) =>
664
670
ConstructorInvokerByTypes . GetOrAdd ( ( type , argumentTypes ) ,
665
671
static t => ConstructorExtractor ( t ) is ConstructorInfo ctor
666
672
? ConstructorInvoker . Create ( ctor )
667
673
: throw new InvalidOperationException ( Strings . ExGivenTypeHasNoOrMoreThanOneCtorWithGivenParameters ) ) ;
668
- #else
674
+
675
+ #endif
676
+ /// <summary>
677
+ /// Gets the public constructor of type <paramref name="type"/>
678
+ /// accepting specified <paramref name="argumentTypes"/>.
679
+ /// </summary>
680
+ /// <param name="type">The type to get the constructor for.</param>
681
+ /// <param name="argumentTypes">The arguments.</param>
682
+ /// <returns>
683
+ /// Appropriate constructor, if a single match is found;
684
+ /// otherwise throws <see cref="InvalidOperationException"/>.
685
+ /// </returns>
686
+ /// <exception cref="InvalidOperationException">
687
+ /// The <paramref name="type"/> has no constructors suitable for <paramref name="argumentTypes"/>
688
+ /// -or- more than one such constructor.
689
+ /// </exception>
690
+ [ Obsolete ] // obsolete to safely make it internal later on or delete
669
691
public static ConstructorInfo GetSingleConstructor ( this Type type , Type [ ] argumentTypes ) =>
670
692
ConstructorInfoByTypes . GetOrAdd ( ( type , argumentTypes ) , ConstructorExtractor )
671
693
?? throw new InvalidOperationException ( Strings . ExGivenTypeHasNoOrMoreThanOneCtorWithGivenParameters ) ;
672
- #endif
673
694
695
+ #if NET8_0_OR_GREATER
674
696
/// <summary>
675
- /// Gets the public constructor of type <paramref name="type"/>
697
+ /// Gets <see cref="ConstructorInvoker"/> of the public constructor of type <paramref name="type"/>
676
698
/// accepting specified <paramref name="argumentTypes"/>.
677
699
/// </summary>
678
700
/// <param name="type">The type to get the constructor for.</param>
@@ -682,14 +704,25 @@ public static ConstructorInfo GetSingleConstructor(this Type type, Type[] argume
682
704
/// otherwise, <see langword="null"/>.
683
705
/// </returns>
684
706
[ CanBeNull ]
685
- #if NET8_0_OR_GREATER
686
- public static ConstructorInvoker GetSingleConstructorInvokerOrDefault ( this Type type , Type [ ] argumentTypes ) =>
707
+ internal static ConstructorInvoker GetSingleConstructorInvokerOrDefault ( this Type type , Type [ ] argumentTypes ) =>
687
708
ConstructorInvokerByTypes . GetOrAdd ( ( type , argumentTypes ) ,
688
709
static t => ConstructorExtractor ( t ) is ConstructorInfo ctor ? ConstructorInvoker . Create ( ctor ) : null ) ;
689
- #else
710
+
711
+ #endif
712
+ /// <summary>
713
+ /// Gets the public constructor of type <paramref name="type"/>
714
+ /// accepting specified <paramref name="argumentTypes"/>.
715
+ /// </summary>
716
+ /// <param name="type">The type to get the constructor for.</param>
717
+ /// <param name="argumentTypes">The arguments.</param>
718
+ /// <returns>
719
+ /// Appropriate constructor, if a single match is found;
720
+ /// otherwise, <see langword="null"/>.
721
+ /// </returns>
722
+ [ CanBeNull ]
723
+ [ Obsolete ] // obsolete to safely make it internal later on
690
724
public static ConstructorInfo GetSingleConstructorOrDefault ( this Type type , Type [ ] argumentTypes ) =>
691
725
ConstructorInfoByTypes . GetOrAdd ( ( type , argumentTypes ) , ConstructorExtractor ) ;
692
- #endif
693
726
694
727
private static readonly Func < ( Type , Type [ ] ) , ConstructorInfo > ConstructorExtractor = t => {
695
728
( var type , var argumentTypes ) = t ;
@@ -943,23 +976,68 @@ public static bool IsGenericMethodSpecificationOf(this MethodInfo method, Method
943
976
|| method . Module == genericMethodDefinition . Module )
944
977
&& method . IsGenericMethod && genericMethodDefinition . IsGenericMethodDefinition ;
945
978
979
+ /// <summary>
980
+ /// Makes generic <see cref="MethodInfo"/> for given definition and type argument
981
+ /// or returns already existing instance from cache.
982
+ /// </summary>
983
+ /// <param name="genericDefinition">Generic definition of method.</param>
984
+ /// <param name="typeArgument">Type argument for final generic method.</param>
985
+ /// <returns>Newly created instance or already existing one.</returns>
946
986
public static MethodInfo CachedMakeGenericMethod ( this MethodInfo genericDefinition , Type typeArgument ) =>
947
987
GenericMethodInstances1 . GetOrAdd ( ( genericDefinition , typeArgument ) , GenericMethodFactory1 ) ;
948
988
989
+ /// <summary>
990
+ /// Makes generic <see cref="MethodInfo"/> for given definition and type arguments
991
+ /// or returns already existing instance from cache.
992
+ /// </summary>
993
+ /// <param name="genericDefinition">Generic definition of method.</param>
994
+ /// <param name="typeArgument1">First type argument for final generic method.</param>
995
+ /// <param name="typeArgument2">Second type argument for final generic method.</param>
996
+ /// <returns>Newly created instance or already existing one.</returns>
949
997
public static MethodInfo CachedMakeGenericMethod ( this MethodInfo genericDefinition , Type typeArgument1 , Type typeArgument2 ) =>
950
998
GenericMethodInstances2 . GetOrAdd ( ( genericDefinition , typeArgument1 , typeArgument2 ) , GenericMethodFactory2 ) ;
951
999
952
1000
#if NET8_0_OR_GREATER
1001
+ /// <summary>
1002
+ /// Makes <see cref="MethodInvoker"/> for generic <see cref="MethodInfo"/> for given definition and type argument
1003
+ /// or returns already existing instance from cache.
1004
+ /// </summary>
1005
+ /// <param name="genericDefinition">Generic definition of method.</param>
1006
+ /// <param name="typeArgument">Type argument for final generic method.</param>
1007
+ /// <returns>Newly created instance or already existing one.</returns>
953
1008
public static MethodInvoker CachedMakeGenericMethodInvoker ( this MethodInfo genericDefinition , Type typeArgument ) =>
954
1009
GenericMethodInvokers1 . GetOrAdd ( ( genericDefinition , typeArgument ) , GenericMethodInvokerFactory1 ) ;
955
1010
1011
+ /// <summary>
1012
+ /// Makes <see cref="MethodInvoker"/> for generic <see cref="MethodInfo"/> for given definition and type arguments
1013
+ /// or returns already existing instance from cache.
1014
+ /// </summary>
1015
+ /// <param name="genericDefinition">Generic definition of method.</param>
1016
+ /// <param name="typeArgument1">First type argument for final generic method.</param>
1017
+ /// <param name="typeArgument2">Second type argument for final generic method.</param>
1018
+ /// <returns>Newly created instance or already existing one.</returns>
956
1019
public static MethodInvoker CachedMakeGenericMethodInvoker ( this MethodInfo genericDefinition , Type typeArgument1 , Type typeArgument2 ) =>
957
1020
GenericMethodInvokers2 . GetOrAdd ( ( genericDefinition , typeArgument1 , typeArgument2 ) , GenericMethodInvokerFactory2 ) ;
958
1021
#endif
959
1022
1023
+ /// <summary>
1024
+ /// Makes generic type of given type definition and type argument
1025
+ /// or returns already existing instance from cache.
1026
+ /// </summary>
1027
+ /// <param name="genericDefinition">Generic type definition.</param>
1028
+ /// <param name="typeArgument">Type argument for final generic type.</param>
1029
+ /// <returns>Newly created instance or already existing one.</returns>
960
1030
public static Type CachedMakeGenericType ( this Type genericDefinition , Type typeArgument ) =>
961
1031
GenericTypeInstances1 . GetOrAdd ( ( genericDefinition , typeArgument ) , GenericTypeFactory1 ) ;
962
1032
1033
+ /// <summary>
1034
+ /// Makes generic type of given type definition and type argument
1035
+ /// or returns already existing instance from cache.
1036
+ /// </summary>
1037
+ /// <param name="genericDefinition">Generic type definition.</param>
1038
+ /// <param name="typeArgument1">First type argument for final generic type.</param>
1039
+ /// <param name="typeArgument2">Second type argument for final generic type.</param>
1040
+ /// <returns>Newly created instance or already existing one.</returns>
963
1041
public static Type CachedMakeGenericType ( this Type genericDefinition , Type typeArgument1 , Type typeArgument2 ) =>
964
1042
GenericTypeInstances2 . GetOrAdd ( ( genericDefinition , typeArgument1 , typeArgument2 ) , GenericTypeFactory2 ) ;
965
1043
@@ -1179,7 +1257,7 @@ internal static bool IsValueTuple(this Type type)
1179
1257
// this stands on the theory that tokens for all generic versions of ValueTuple
1180
1258
// go one after another.
1181
1259
var currentToken = type . MetadataToken ;
1182
- return ( ( currentToken >= ValueTuple1 ) && currentToken <= ValueTuple8 )
1260
+ return ( ( currentToken >= ValueTuple1MetadataToken ) && currentToken <= ValueTuple8MetadataToken )
1183
1261
&& ReferenceEquals ( type . Module , SystemCoreLibModule ) ;
1184
1262
}
1185
1263
0 commit comments