@@ -47,17 +47,18 @@ public int GetHashCode((Type, Type[]) obj)
4747
4848 private static readonly object EmitLock = new object ( ) ;
4949 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 ;
5252 private static readonly Module SystemCoreLibModule = WellKnownTypes . NullableOfT . Module ;
5353 private static readonly Type CompilerGeneratedAttributeType = typeof ( CompilerGeneratedAttribute ) ;
5454 private static readonly string TypeHelperNamespace = typeof ( TypeHelper ) . Namespace ;
5555
56+ #region Caches and cache items factories
5657#if NET8_0_OR_GREATER
5758 private static readonly ConcurrentDictionary < ( Type , Type [ ] ) , ConstructorInvoker > ConstructorInvokerByTypes =
58- #else
59- private static readonly ConcurrentDictionary < ( Type , Type [ ] ) , ConstructorInfo > ConstructorInfoByTypes =
59+ new ( new TypesEqualityComparer ( ) ) ;
6060#endif
61+ private static readonly ConcurrentDictionary < ( Type , Type [ ] ) , ConstructorInfo > ConstructorInfoByTypes =
6162 new ( new TypesEqualityComparer ( ) ) ;
6263
6364 private static readonly ConcurrentDictionary < Type , Type [ ] > OrderedInterfaces = new ( ) ;
@@ -71,16 +72,11 @@ public int GetHashCode((Type, Type[]) obj)
7172 private static readonly ConcurrentDictionary < ( MethodInfo , Type ) , MethodInfo > GenericMethodInstances1 = new ( ) ;
7273
7374 private static readonly ConcurrentDictionary < ( MethodInfo , Type , Type ) , MethodInfo > GenericMethodInstances2 = new ( ) ;
74-
7575#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 ( ) ;
7876
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 ( ) ;
8178
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 ( ) ;
8480#endif
8581
8682 private static readonly ConcurrentDictionary < ( Type , Type ) , Type > GenericTypeInstances1 = new ( ) ;
@@ -93,11 +89,21 @@ public int GetHashCode((Type, Type[]) obj)
9389 private static readonly Func < ( MethodInfo genericDefinition , Type typeArgument1 , Type typeArgument2 ) , MethodInfo > GenericMethodFactory2 =
9490 key => key . genericDefinition . MakeGenericMethod ( key . typeArgument1 , key . typeArgument2 ) ;
9591
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
98105
99- private static readonly Func < ( Type genericDefinition , Type typeArgument1 , Type typeArgument2 ) , Type > GenericTypeFactory2 = key =>
100- key . genericDefinition . MakeGenericType ( key . typeArgument1 , key . typeArgument2 ) ;
106+ #endregion
101107
102108 private static int createDummyTypeNumber = 0 ;
103109 private static AssemblyBuilder assemblyBuilder ;
@@ -645,34 +651,50 @@ public static object Activate(this Type type, Type[] genericArguments, params ob
645651 }
646652 }
647653
654+ #if NET8_0_OR_GREATER
648655 /// <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"/>
650657 /// accepting specified <paramref name="argumentTypes"/>.
651658 /// </summary>
652659 /// <param name="type">The type to get the constructor for.</param>
653660 /// <param name="argumentTypes">The arguments.</param>
654661 /// <returns>
655- /// Appropriate constructor, if a single match is found;
662+ /// Appropriate constructor invoker , if a single match is found;
656663 /// otherwise throws <see cref="InvalidOperationException"/>.
657664 /// </returns>
658665 /// <exception cref="InvalidOperationException">
659666 /// The <paramref name="type"/> has no constructors suitable for <paramref name="argumentTypes"/>
660667 /// -or- more than one such constructor.
661668 /// </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 ) =>
664670 ConstructorInvokerByTypes . GetOrAdd ( ( type , argumentTypes ) ,
665671 static t => ConstructorExtractor ( t ) is ConstructorInfo ctor
666672 ? ConstructorInvoker . Create ( ctor )
667673 : 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
669691 public static ConstructorInfo GetSingleConstructor ( this Type type , Type [ ] argumentTypes ) =>
670692 ConstructorInfoByTypes . GetOrAdd ( ( type , argumentTypes ) , ConstructorExtractor )
671693 ?? throw new InvalidOperationException ( Strings . ExGivenTypeHasNoOrMoreThanOneCtorWithGivenParameters ) ;
672- #endif
673694
695+ #if NET8_0_OR_GREATER
674696 /// <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"/>
676698 /// accepting specified <paramref name="argumentTypes"/>.
677699 /// </summary>
678700 /// <param name="type">The type to get the constructor for.</param>
@@ -682,14 +704,25 @@ public static ConstructorInfo GetSingleConstructor(this Type type, Type[] argume
682704 /// otherwise, <see langword="null"/>.
683705 /// </returns>
684706 [ 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 ) =>
687708 ConstructorInvokerByTypes . GetOrAdd ( ( type , argumentTypes ) ,
688709 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
690724 public static ConstructorInfo GetSingleConstructorOrDefault ( this Type type , Type [ ] argumentTypes ) =>
691725 ConstructorInfoByTypes . GetOrAdd ( ( type , argumentTypes ) , ConstructorExtractor ) ;
692- #endif
693726
694727 private static readonly Func < ( Type , Type [ ] ) , ConstructorInfo > ConstructorExtractor = t => {
695728 ( var type , var argumentTypes ) = t ;
@@ -943,23 +976,68 @@ public static bool IsGenericMethodSpecificationOf(this MethodInfo method, Method
943976 || method . Module == genericMethodDefinition . Module )
944977 && method . IsGenericMethod && genericMethodDefinition . IsGenericMethodDefinition ;
945978
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>
946986 public static MethodInfo CachedMakeGenericMethod ( this MethodInfo genericDefinition , Type typeArgument ) =>
947987 GenericMethodInstances1 . GetOrAdd ( ( genericDefinition , typeArgument ) , GenericMethodFactory1 ) ;
948988
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>
949997 public static MethodInfo CachedMakeGenericMethod ( this MethodInfo genericDefinition , Type typeArgument1 , Type typeArgument2 ) =>
950998 GenericMethodInstances2 . GetOrAdd ( ( genericDefinition , typeArgument1 , typeArgument2 ) , GenericMethodFactory2 ) ;
951999
9521000#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>
9531008 public static MethodInvoker CachedMakeGenericMethodInvoker ( this MethodInfo genericDefinition , Type typeArgument ) =>
9541009 GenericMethodInvokers1 . GetOrAdd ( ( genericDefinition , typeArgument ) , GenericMethodInvokerFactory1 ) ;
9551010
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>
9561019 public static MethodInvoker CachedMakeGenericMethodInvoker ( this MethodInfo genericDefinition , Type typeArgument1 , Type typeArgument2 ) =>
9571020 GenericMethodInvokers2 . GetOrAdd ( ( genericDefinition , typeArgument1 , typeArgument2 ) , GenericMethodInvokerFactory2 ) ;
9581021#endif
9591022
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>
9601030 public static Type CachedMakeGenericType ( this Type genericDefinition , Type typeArgument ) =>
9611031 GenericTypeInstances1 . GetOrAdd ( ( genericDefinition , typeArgument ) , GenericTypeFactory1 ) ;
9621032
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>
9631041 public static Type CachedMakeGenericType ( this Type genericDefinition , Type typeArgument1 , Type typeArgument2 ) =>
9641042 GenericTypeInstances2 . GetOrAdd ( ( genericDefinition , typeArgument1 , typeArgument2 ) , GenericTypeFactory2 ) ;
9651043
@@ -1179,7 +1257,7 @@ internal static bool IsValueTuple(this Type type)
11791257 // this stands on the theory that tokens for all generic versions of ValueTuple
11801258 // go one after another.
11811259 var currentToken = type . MetadataToken ;
1182- return ( ( currentToken >= ValueTuple1 ) && currentToken <= ValueTuple8 )
1260+ return ( ( currentToken >= ValueTuple1MetadataToken ) && currentToken <= ValueTuple8MetadataToken )
11831261 && ReferenceEquals ( type . Module , SystemCoreLibModule ) ;
11841262 }
11851263
0 commit comments