From 7b4f287348a29f8db4cdca2a2ac1341a82299ee2 Mon Sep 17 00:00:00 2001 From: Marco Silipo Date: Mon, 18 Dec 2023 14:41:53 +0100 Subject: [PATCH] fixing memory leak in CreateInstance due to hashkey issue --- .../CreateInstanceViaJsonSerializerTest.cs | 167 ++ X39.Util/TypeExtensionMethods.cs | 143 +- X39.Util/TypeExtensions.t4.cs | 1906 ++--------------- X39.Util/TypeExtensions.t4.tt | 100 +- X39.Util/X39.Util.csproj | 11 +- 5 files changed, 469 insertions(+), 1858 deletions(-) create mode 100644 X39.Util.Tests/CreateInstanceViaJsonSerializerTest.cs diff --git a/X39.Util.Tests/CreateInstanceViaJsonSerializerTest.cs b/X39.Util.Tests/CreateInstanceViaJsonSerializerTest.cs new file mode 100644 index 0000000..ea370fc --- /dev/null +++ b/X39.Util.Tests/CreateInstanceViaJsonSerializerTest.cs @@ -0,0 +1,167 @@ +#if NET7_0_OR_GREATER +using System; +using System.Linq; +using System.Text.Json; +using System.Text.Json.Serialization; +using NUnit.Framework; + +namespace X39.Util.Tests; + +public class CreateInstanceViaJsonSerializerTest +{ + #region SerializerTest + + public class PrimitivePair + { + public PrimitiveString String { get; set; } + public PrimitiveUShort UShort { get; set; } + } + + public class StronglyTypedPrimitiveConverterFactory : JsonConverterFactory + { +#pragma warning disable CS0618 + private interface ICreator + { + public object Value { get; } + } + + private class Creator : ICreator + where TType : IStronglyTypedPrimitive, new() + { + public object Value { get; } + + public Creator(TPrimitive primitive) + { + Value = new TType {Value = primitive}; + } + } + + private class StronglyTypedPrimitiveConverter : JsonConverter + where TType : IStronglyTypedPrimitive, new() + { + public override TType? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (!IsPrimitiveTokenType(reader.TokenType)) + return JsonSerializer.Deserialize(ref reader); + + if (typeof(TPrimitive).IsEquivalentTo(typeof(string))) + { + var value = reader.GetString() ?? string.Empty; + + return (TType) typeof(Creator<,>) + .MakeGenericType(typeof(TType), typeof(string)) + .CreateInstanceWith(value) + .Value; + } + + if (typeof(TPrimitive).IsEquivalentTo(typeof(ushort))) + { + var value = reader.GetUInt16(); + + return (TType) typeof(Creator<,>) + .MakeGenericType(typeof(TType), typeof(ushort)) + .CreateInstanceWith(value) + .Value; + } + + throw new NotSupportedException($"The primitive {typeof(TPrimitive).FullName()} is not supported"); + } + + public override void Write(Utf8JsonWriter writer, TType value, JsonSerializerOptions options) + { + switch (value.Value) + { + case string stringValue: + writer.WriteStringValue(stringValue); + break; + case ushort ushortValue: + writer.WriteNumberValue(ushortValue); + break; + default: + throw new NotSupportedException( + $"The primitive {typeof(TPrimitive).FullName()} is not supported"); + } + } + + private static bool IsPrimitiveTokenType(JsonTokenType tokenType) + { + return tokenType is + JsonTokenType.String or + JsonTokenType.Number; + } + } + + /// + public override bool CanConvert(Type typeToConvert) + { + return typeof(IStronglyTypedPrimitive).IsAssignableFrom(typeToConvert); + } + + /// + public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options) + { + var interfaceType = typeToConvert.GetInterfaces() + .First((q) => q.IsGenericType(typeof(IStronglyTypedPrimitive<,>))); + return typeof(StronglyTypedPrimitiveConverter<,>) + .MakeGenericType(interfaceType.GetGenericArguments()) + .CreateInstanceWith(); + } +#pragma warning restore CS0618 + } + + public interface IStronglyTypedPrimitive + { + } + +#pragma warning disable CS0618 + public interface IStronglyTypedPrimitive : IStronglyTypedPrimitive + where TType : IStronglyTypedPrimitive, new() +#pragma warning restore CS0618 + { + public TPrimitive Value { get; init; } + } + + public readonly struct PrimitiveString : IStronglyTypedPrimitive + { + public PrimitiveString(string value) + { + Value = value; + } + + public string Value { get; init; } + } + + public readonly struct PrimitiveUShort : IStronglyTypedPrimitive + { + public PrimitiveUShort(ushort value) + { + Value = value; + } + + public ushort Value { get; init; } + } + + #endregion + + [Test] + public void Test() + { + const string json = "{\"String\":\"AB\",\"UShort\":123}"; + + for (var i = 0; i < 1000; i++) + { + JsonSerializer.Deserialize(json, new JsonSerializerOptions + { + Converters = + { + new StronglyTypedPrimitiveConverterFactory() + } + }); + } + + Assert.AreEqual(4, TypeExtensionMethods.CreateInstanceCache.Count); + } +} + + +#endif \ No newline at end of file diff --git a/X39.Util/TypeExtensionMethods.cs b/X39.Util/TypeExtensionMethods.cs index 72dd887..d4369ab 100644 --- a/X39.Util/TypeExtensionMethods.cs +++ b/X39.Util/TypeExtensionMethods.cs @@ -18,19 +18,122 @@ namespace X39.Util; public static partial class TypeExtensionMethods { // ReSharper disable once IdentifierTypo - private static readonly RWLConcurrentDictionary DeNulledTypeCache = new(); - private static readonly RWLConcurrentDictionary FullNameCache = new(); - private static readonly RWLConcurrentDictionary NameCache = new(); - private static readonly RWLConcurrentDictionary BaseTypeCache = new(); - private static readonly RWLConcurrentDictionary IsObsoleteCache = new(); - -#if NET5_0_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NET47 || NET471 || NET472 - private static readonly RWLConcurrentDictionary<(Type returnType, Type[] arguments), Delegate> CreateInstanceCache = - new(); + internal static readonly RWLConcurrentDictionary DeNulledTypeCache = new(); + internal static readonly RWLConcurrentDictionary FullNameCache = new(); + internal static readonly RWLConcurrentDictionary NameCache = new(); + internal static readonly RWLConcurrentDictionary BaseTypeCache = new(); + internal static readonly RWLConcurrentDictionary IsObsoleteCache = new(); + + internal struct InstanceCacheKey : IEquatable + { + public bool Equals(InstanceCacheKey other) + { + return Type.IsEquivalentTo(other.Type) + && Arguments.Length == other.Arguments.Length + && Arguments.Zip(other.Arguments, (l, r) => l.IsEquivalentTo(r)).All((q) => q); + } + + public override bool Equals(object? obj) + { + return obj is InstanceCacheKey other && Equals(other); + } + + public override int GetHashCode() + { +#if NET5_0_OR_GREATER || NETSTANDARD2_1 + switch (Arguments.Length) + { + case 0: return Type.GetHashCode(); + case 1: + return HashCode.Combine( + Type.GetHashCode(), + Arguments[0].GetHashCode()); + case 2: + return HashCode.Combine( + Type.GetHashCode(), + Arguments[0].GetHashCode(), + Arguments[1].GetHashCode()); + case 3: + return HashCode.Combine( + Type.GetHashCode(), + Arguments[0].GetHashCode(), + Arguments[1].GetHashCode(), + Arguments[2].GetHashCode()); + case 4: + return HashCode.Combine( + Type.GetHashCode(), + Arguments[0].GetHashCode(), + Arguments[1].GetHashCode(), + Arguments[2].GetHashCode(), + Arguments[3].GetHashCode()); + case 5: + return HashCode.Combine( + Type.GetHashCode(), + Arguments[0].GetHashCode(), + Arguments[1].GetHashCode(), + Arguments[2].GetHashCode(), + Arguments[3].GetHashCode(), + Arguments[4].GetHashCode()); + case 6: + return HashCode.Combine( + Type.GetHashCode(), + Arguments[0].GetHashCode(), + Arguments[1].GetHashCode(), + Arguments[2].GetHashCode(), + Arguments[3].GetHashCode(), + Arguments[4].GetHashCode(), + Arguments[5].GetHashCode()); + case 7: + return HashCode.Combine( + Type.GetHashCode(), + Arguments[0].GetHashCode(), + Arguments[1].GetHashCode(), + Arguments[2].GetHashCode(), + Arguments[3].GetHashCode(), + Arguments[4].GetHashCode(), + Arguments[5].GetHashCode(), + Arguments[6].GetHashCode()); + default: + var hashCode = new HashCode(); + hashCode.Add(Type.GetHashCode()); + foreach (var arg in Arguments) + { + hashCode.Add(arg.GetHashCode()); + } + + return hashCode.ToHashCode(); + } #else - private static readonly RWLConcurrentDictionary, Delegate> CreateInstanceCache = - new(); + unchecked + { + return Arguments.Select((q) => q.GetHashCode()).Aggregate( + Type.GetHashCode(), + (l, r) => (int)(r + 0x9e3779b9 + (l << 6) + (l >> 2))); + } #endif + } + + public static bool operator ==(InstanceCacheKey left, InstanceCacheKey right) + { + return left.Equals(right); + } + + public static bool operator !=(InstanceCacheKey left, InstanceCacheKey right) + { + return !left.Equals(right); + } + + public InstanceCacheKey(Type type, Type[] arguments) + { + Type = type; + Arguments = arguments; + } + + public Type Type; + public Type[] Arguments; + } + + internal static readonly RWLConcurrentDictionary CreateInstanceCache = new(); /// /// Clears all cached data for the methods provided by . @@ -42,6 +145,7 @@ public static void ClearCache() NameCache.Clear(); BaseTypeCache.Clear(); CreateInstanceCache.Clear(); + ClearDynCache(); } /// @@ -183,11 +287,7 @@ public static Type GetDeNulledType(this Type type) /// The newly created instance public static object CreateInstance(this Type t) { -#if NET5_0_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NET47 || NET471 || NET472 - var key = (t, Type.EmptyTypes); -#else - var key = Tuple.Create(t, Type.EmptyTypes); -#endif + var key = new InstanceCacheKey(t, Type.EmptyTypes); if (CreateInstanceCache.TryGetValue(key, out var @delegate)) return @delegate.DynamicInvoke()!; CreateInstanceCache[key] = @delegate = Expression.Lambda(Expression.New(t)).Compile(); @@ -252,13 +352,9 @@ public static object CreateInstanceWith(this Type t, Type[] types, object?[] arg Debug.Assert( types.Length == args.Length, $"The count of args ({args.Length}) is not equal to the count of types ({types.Length})"); -#if NET5_0_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NET47 || NET471 || NET472 - var key = (t, types); -#else - var key = Tuple.Create(t, types); -#endif + var key = new InstanceCacheKey(t, types); if (CreateInstanceCache.TryGetValue(key, out var @delegate)) - return @delegate.DynamicInvoke()!; + return @delegate.DynamicInvoke(args)!; var constructor = t.GetConstructor( bindingAttr: System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | @@ -277,6 +373,7 @@ public static object CreateInstanceWith(this Type t, Type[] types, object?[] arg CreateInstanceCache[key] = @delegate = lambdaExpression.Compile(); return @delegate.DynamicInvoke(args)!; } + /// /// Creates a new instance of the with the given . /// The method will use the given to determine which constructor to use. @@ -384,7 +481,7 @@ public static bool IsObsolete(this Type type, bool useCache = true) return flag; var attribute = type.GetCustomAttribute(); var tmp = attribute is not null; - if (tmp is false && type.DeclaringType?.IsObsolete(useCache: useCache) is {} classObsolete) + if (tmp is false && type.DeclaringType?.IsObsolete(useCache: useCache) is { } classObsolete) tmp = classObsolete; if (useCache) IsObsoleteCache[type] = tmp; diff --git a/X39.Util/TypeExtensions.t4.cs b/X39.Util/TypeExtensions.t4.cs index 275af41..8c5a2a4 100644 --- a/X39.Util/TypeExtensions.t4.cs +++ b/X39.Util/TypeExtensions.t4.cs @@ -4,40 +4,63 @@ namespace X39.Util; public static partial class TypeExtensionMethods { - + private static void ClearDynCache() + { + CreateInstanceDelegate1Cache.Clear(); + CreateInstanceDelegate2Cache.Clear(); + CreateInstanceDelegate3Cache.Clear(); + CreateInstanceDelegate4Cache.Clear(); + CreateInstanceDelegate5Cache.Clear(); + CreateInstanceDelegate6Cache.Clear(); #if NET5_0_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NET47 || NET471 || NET472 - private static readonly Dictionary<( - Type, - Type - ), Delegate> CreateInstanceDelegate1Cache = new(); -#else - private static readonly Dictionary, Delegate> CreateInstanceDelegate1Cache = new(); + CreateInstanceDelegate7Cache.Clear(); #endif - public static object CreateInstance( - this Type t, - TArg1 arg1) - { #if NET5_0_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NET47 || NET471 || NET472 - var key = ( - t, - typeof(TArg1) - ); -#else - var key = Tuple.Create( - t, - typeof(TArg1) - ); + CreateInstanceDelegate8Cache.Clear(); +#endif +#if NET5_0_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NET47 || NET471 || NET472 + CreateInstanceDelegate9Cache.Clear(); +#endif +#if NET5_0_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NET47 || NET471 || NET472 + CreateInstanceDelegate10Cache.Clear(); +#endif +#if NET5_0_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NET47 || NET471 || NET472 + CreateInstanceDelegate11Cache.Clear(); +#endif +#if NET5_0_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NET47 || NET471 || NET472 + CreateInstanceDelegate12Cache.Clear(); +#endif +#if NET5_0_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NET47 || NET471 || NET472 + CreateInstanceDelegate13Cache.Clear(); #endif +#if NET5_0_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NET47 || NET471 || NET472 + CreateInstanceDelegate14Cache.Clear(); +#endif +#if NET5_0_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NET47 || NET471 || NET472 + CreateInstanceDelegate15Cache.Clear(); +#endif +#if NET5_0_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NET47 || NET471 || NET472 + CreateInstanceDelegate16Cache.Clear(); +#endif +#if NET5_0_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NET47 || NET471 || NET472 + CreateInstanceDelegate17Cache.Clear(); +#endif +#if NET5_0_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NET47 || NET471 || NET472 + CreateInstanceDelegate18Cache.Clear(); +#endif +#if NET5_0_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NET47 || NET471 || NET472 + CreateInstanceDelegate19Cache.Clear(); +#endif + } + + internal static readonly Dictionary CreateInstanceDelegate1Cache = new(); + public static object CreateInstance(this Type t, TArg1 arg1) + { + var key = new InstanceCacheKey(t, new[]{typeof(TArg1)}); if (CreateInstanceDelegate1Cache.TryGetValue(key, out var del)) - return del.DynamicInvoke(arg1 - ) + return del.DynamicInvoke(arg1) ?? throw new NullReferenceException("Constructor yielded null result."); - var constructor = t.GetConstructor(new[] { - typeof(TArg1) - }); + var constructor = t.GetConstructor(new[] {typeof(TArg1)}); if (constructor == null) { var ex = new InvalidOperationException("No matching constructor existing."); @@ -56,46 +79,14 @@ public static object CreateInstance( ?? throw new NullReferenceException("Constructor yielded null result."); } -#if NET5_0_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NET47 || NET471 || NET472 - private static readonly Dictionary<( - Type, - Type, - Type - ), Delegate> CreateInstanceDelegate2Cache = new(); -#else - private static readonly Dictionary, Delegate> CreateInstanceDelegate2Cache = new(); -#endif - public static object CreateInstance( - this Type t, - TArg1 arg1, - TArg2 arg2) + internal static readonly Dictionary CreateInstanceDelegate2Cache = new(); + public static object CreateInstance(this Type t, TArg1 arg1, TArg2 arg2) { -#if NET5_0_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NET47 || NET471 || NET472 - var key = ( - t, - typeof(TArg1), - typeof(TArg2) - ); -#else - var key = Tuple.Create( - t, - typeof(TArg1), - typeof(TArg2) - ); -#endif + var key = new InstanceCacheKey(t, new[]{typeof(TArg1), typeof(TArg2)}); if (CreateInstanceDelegate2Cache.TryGetValue(key, out var del)) - return del.DynamicInvoke(arg1, - arg2 - ) + return del.DynamicInvoke(arg1, arg2) ?? throw new NullReferenceException("Constructor yielded null result."); - var constructor = t.GetConstructor(new[] { - typeof(TArg1), - typeof(TArg2) - }); + var constructor = t.GetConstructor(new[] {typeof(TArg1), typeof(TArg2)}); if (constructor == null) { var ex = new InvalidOperationException("No matching constructor existing."); @@ -117,53 +108,14 @@ public static object CreateInstance( ?? throw new NullReferenceException("Constructor yielded null result."); } -#if NET5_0_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NET47 || NET471 || NET472 - private static readonly Dictionary<( - Type, - Type, - Type, - Type - ), Delegate> CreateInstanceDelegate3Cache = new(); -#else - private static readonly Dictionary, Delegate> CreateInstanceDelegate3Cache = new(); -#endif - public static object CreateInstance( - this Type t, - TArg1 arg1, - TArg2 arg2, - TArg3 arg3) + internal static readonly Dictionary CreateInstanceDelegate3Cache = new(); + public static object CreateInstance(this Type t, TArg1 arg1, TArg2 arg2, TArg3 arg3) { -#if NET5_0_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NET47 || NET471 || NET472 - var key = ( - t, - typeof(TArg1), - typeof(TArg2), - typeof(TArg3) - ); -#else - var key = Tuple.Create( - t, - typeof(TArg1), - typeof(TArg2), - typeof(TArg3) - ); -#endif + var key = new InstanceCacheKey(t, new[]{typeof(TArg1), typeof(TArg2), typeof(TArg3)}); if (CreateInstanceDelegate3Cache.TryGetValue(key, out var del)) - return del.DynamicInvoke(arg1, - arg2, - arg3 - ) + return del.DynamicInvoke(arg1, arg2, arg3) ?? throw new NullReferenceException("Constructor yielded null result."); - var constructor = t.GetConstructor(new[] { - typeof(TArg1), - typeof(TArg2), - typeof(TArg3) - }); + var constructor = t.GetConstructor(new[] {typeof(TArg1), typeof(TArg2), typeof(TArg3)}); if (constructor == null) { var ex = new InvalidOperationException("No matching constructor existing."); @@ -188,60 +140,14 @@ public static object CreateInstance( ?? throw new NullReferenceException("Constructor yielded null result."); } -#if NET5_0_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NET47 || NET471 || NET472 - private static readonly Dictionary<( - Type, - Type, - Type, - Type, - Type - ), Delegate> CreateInstanceDelegate4Cache = new(); -#else - private static readonly Dictionary, Delegate> CreateInstanceDelegate4Cache = new(); -#endif - public static object CreateInstance( - this Type t, - TArg1 arg1, - TArg2 arg2, - TArg3 arg3, - TArg4 arg4) + internal static readonly Dictionary CreateInstanceDelegate4Cache = new(); + public static object CreateInstance(this Type t, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4) { -#if NET5_0_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NET47 || NET471 || NET472 - var key = ( - t, - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4) - ); -#else - var key = Tuple.Create( - t, - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4) - ); -#endif + var key = new InstanceCacheKey(t, new[]{typeof(TArg1), typeof(TArg2), typeof(TArg3), typeof(TArg4)}); if (CreateInstanceDelegate4Cache.TryGetValue(key, out var del)) - return del.DynamicInvoke(arg1, - arg2, - arg3, - arg4 - ) + return del.DynamicInvoke(arg1, arg2, arg3, arg4) ?? throw new NullReferenceException("Constructor yielded null result."); - var constructor = t.GetConstructor(new[] { - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4) - }); + var constructor = t.GetConstructor(new[] {typeof(TArg1), typeof(TArg2), typeof(TArg3), typeof(TArg4)}); if (constructor == null) { var ex = new InvalidOperationException("No matching constructor existing."); @@ -269,67 +175,14 @@ public static object CreateInstance( ?? throw new NullReferenceException("Constructor yielded null result."); } -#if NET5_0_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NET47 || NET471 || NET472 - private static readonly Dictionary<( - Type, - Type, - Type, - Type, - Type, - Type - ), Delegate> CreateInstanceDelegate5Cache = new(); -#else - private static readonly Dictionary, Delegate> CreateInstanceDelegate5Cache = new(); -#endif - public static object CreateInstance( - this Type t, - TArg1 arg1, - TArg2 arg2, - TArg3 arg3, - TArg4 arg4, - TArg5 arg5) + internal static readonly Dictionary CreateInstanceDelegate5Cache = new(); + public static object CreateInstance(this Type t, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5) { -#if NET5_0_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NET47 || NET471 || NET472 - var key = ( - t, - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4), - typeof(TArg5) - ); -#else - var key = Tuple.Create( - t, - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4), - typeof(TArg5) - ); -#endif + var key = new InstanceCacheKey(t, new[]{typeof(TArg1), typeof(TArg2), typeof(TArg3), typeof(TArg4), typeof(TArg5)}); if (CreateInstanceDelegate5Cache.TryGetValue(key, out var del)) - return del.DynamicInvoke(arg1, - arg2, - arg3, - arg4, - arg5 - ) + return del.DynamicInvoke(arg1, arg2, arg3, arg4, arg5) ?? throw new NullReferenceException("Constructor yielded null result."); - var constructor = t.GetConstructor(new[] { - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4), - typeof(TArg5) - }); + var constructor = t.GetConstructor(new[] {typeof(TArg1), typeof(TArg2), typeof(TArg3), typeof(TArg4), typeof(TArg5)}); if (constructor == null) { var ex = new InvalidOperationException("No matching constructor existing."); @@ -360,74 +213,14 @@ public static object CreateInstance( ?? throw new NullReferenceException("Constructor yielded null result."); } -#if NET5_0_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NET47 || NET471 || NET472 - private static readonly Dictionary<( - Type, - Type, - Type, - Type, - Type, - Type, - Type - ), Delegate> CreateInstanceDelegate6Cache = new(); -#else - private static readonly Dictionary, Delegate> CreateInstanceDelegate6Cache = new(); -#endif - public static object CreateInstance( - this Type t, - TArg1 arg1, - TArg2 arg2, - TArg3 arg3, - TArg4 arg4, - TArg5 arg5, - TArg6 arg6) + internal static readonly Dictionary CreateInstanceDelegate6Cache = new(); + public static object CreateInstance(this Type t, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6) { -#if NET5_0_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NET47 || NET471 || NET472 - var key = ( - t, - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4), - typeof(TArg5), - typeof(TArg6) - ); -#else - var key = Tuple.Create( - t, - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4), - typeof(TArg5), - typeof(TArg6) - ); -#endif + var key = new InstanceCacheKey(t, new[]{typeof(TArg1), typeof(TArg2), typeof(TArg3), typeof(TArg4), typeof(TArg5), typeof(TArg6)}); if (CreateInstanceDelegate6Cache.TryGetValue(key, out var del)) - return del.DynamicInvoke(arg1, - arg2, - arg3, - arg4, - arg5, - arg6 - ) + return del.DynamicInvoke(arg1, arg2, arg3, arg4, arg5, arg6) ?? throw new NullReferenceException("Constructor yielded null result."); - var constructor = t.GetConstructor(new[] { - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4), - typeof(TArg5), - typeof(TArg6) - }); + var constructor = t.GetConstructor(new[] {typeof(TArg1), typeof(TArg2), typeof(TArg3), typeof(TArg4), typeof(TArg5), typeof(TArg6)}); if (constructor == null) { var ex = new InvalidOperationException("No matching constructor existing."); @@ -462,81 +255,14 @@ public static object CreateInstance( } #if NET5_0_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NET47 || NET471 || NET472 -#if NET5_0_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NET47 || NET471 || NET472 - private static readonly Dictionary<( - Type, - Type, - Type, - Type, - Type, - Type, - Type, - Type - ), Delegate> CreateInstanceDelegate7Cache = new(); -#else - private static readonly Dictionary, Delegate> CreateInstanceDelegate7Cache = new(); -#endif - public static object CreateInstance( - this Type t, - TArg1 arg1, - TArg2 arg2, - TArg3 arg3, - TArg4 arg4, - TArg5 arg5, - TArg6 arg6, - TArg7 arg7) + internal static readonly Dictionary CreateInstanceDelegate7Cache = new(); + public static object CreateInstance(this Type t, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7) { -#if NET5_0_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NET47 || NET471 || NET472 - var key = ( - t, - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4), - typeof(TArg5), - typeof(TArg6), - typeof(TArg7) - ); -#else - var key = Tuple.Create( - t, - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4), - typeof(TArg5), - typeof(TArg6), - typeof(TArg7) - ); -#endif + var key = new InstanceCacheKey(t, new[]{typeof(TArg1), typeof(TArg2), typeof(TArg3), typeof(TArg4), typeof(TArg5), typeof(TArg6), typeof(TArg7)}); if (CreateInstanceDelegate7Cache.TryGetValue(key, out var del)) - return del.DynamicInvoke(arg1, - arg2, - arg3, - arg4, - arg5, - arg6, - arg7 - ) + return del.DynamicInvoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7) ?? throw new NullReferenceException("Constructor yielded null result."); - var constructor = t.GetConstructor(new[] { - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4), - typeof(TArg5), - typeof(TArg6), - typeof(TArg7) - }); + var constructor = t.GetConstructor(new[] {typeof(TArg1), typeof(TArg2), typeof(TArg3), typeof(TArg4), typeof(TArg5), typeof(TArg6), typeof(TArg7)}); if (constructor == null) { var ex = new InvalidOperationException("No matching constructor existing."); @@ -575,88 +301,14 @@ public static object CreateInstance CreateInstanceDelegate8Cache = new(); -#else - private static readonly Dictionary, Delegate> CreateInstanceDelegate8Cache = new(); -#endif - public static object CreateInstance( - this Type t, - TArg1 arg1, - TArg2 arg2, - TArg3 arg3, - TArg4 arg4, - TArg5 arg5, - TArg6 arg6, - TArg7 arg7, - TArg8 arg8) + internal static readonly Dictionary CreateInstanceDelegate8Cache = new(); + public static object CreateInstance(this Type t, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8) { -#if NET5_0_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NET47 || NET471 || NET472 - var key = ( - t, - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4), - typeof(TArg5), - typeof(TArg6), - typeof(TArg7), - typeof(TArg8) - ); -#else - var key = Tuple.Create( - t, - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4), - typeof(TArg5), - typeof(TArg6), - typeof(TArg7), - typeof(TArg8) - ); -#endif + var key = new InstanceCacheKey(t, new[]{typeof(TArg1), typeof(TArg2), typeof(TArg3), typeof(TArg4), typeof(TArg5), typeof(TArg6), typeof(TArg7), typeof(TArg8)}); if (CreateInstanceDelegate8Cache.TryGetValue(key, out var del)) - return del.DynamicInvoke(arg1, - arg2, - arg3, - arg4, - arg5, - arg6, - arg7, - arg8 - ) + return del.DynamicInvoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) ?? throw new NullReferenceException("Constructor yielded null result."); - var constructor = t.GetConstructor(new[] { - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4), - typeof(TArg5), - typeof(TArg6), - typeof(TArg7), - typeof(TArg8) - }); + var constructor = t.GetConstructor(new[] {typeof(TArg1), typeof(TArg2), typeof(TArg3), typeof(TArg4), typeof(TArg5), typeof(TArg6), typeof(TArg7), typeof(TArg8)}); if (constructor == null) { var ex = new InvalidOperationException("No matching constructor existing."); @@ -698,95 +350,14 @@ public static object CreateInstance CreateInstanceDelegate9Cache = new(); -#else - private static readonly Dictionary, Delegate> CreateInstanceDelegate9Cache = new(); -#endif - public static object CreateInstance( - this Type t, - TArg1 arg1, - TArg2 arg2, - TArg3 arg3, - TArg4 arg4, - TArg5 arg5, - TArg6 arg6, - TArg7 arg7, - TArg8 arg8, - TArg9 arg9) + internal static readonly Dictionary CreateInstanceDelegate9Cache = new(); + public static object CreateInstance(this Type t, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8, TArg9 arg9) { -#if NET5_0_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NET47 || NET471 || NET472 - var key = ( - t, - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4), - typeof(TArg5), - typeof(TArg6), - typeof(TArg7), - typeof(TArg8), - typeof(TArg9) - ); -#else - var key = Tuple.Create( - t, - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4), - typeof(TArg5), - typeof(TArg6), - typeof(TArg7), - typeof(TArg8), - typeof(TArg9) - ); -#endif + var key = new InstanceCacheKey(t, new[]{typeof(TArg1), typeof(TArg2), typeof(TArg3), typeof(TArg4), typeof(TArg5), typeof(TArg6), typeof(TArg7), typeof(TArg8), typeof(TArg9)}); if (CreateInstanceDelegate9Cache.TryGetValue(key, out var del)) - return del.DynamicInvoke(arg1, - arg2, - arg3, - arg4, - arg5, - arg6, - arg7, - arg8, - arg9 - ) + return del.DynamicInvoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) ?? throw new NullReferenceException("Constructor yielded null result."); - var constructor = t.GetConstructor(new[] { - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4), - typeof(TArg5), - typeof(TArg6), - typeof(TArg7), - typeof(TArg8), - typeof(TArg9) - }); + var constructor = t.GetConstructor(new[] {typeof(TArg1), typeof(TArg2), typeof(TArg3), typeof(TArg4), typeof(TArg5), typeof(TArg6), typeof(TArg7), typeof(TArg8), typeof(TArg9)}); if (constructor == null) { var ex = new InvalidOperationException("No matching constructor existing."); @@ -831,102 +402,14 @@ public static object CreateInstance CreateInstanceDelegate10Cache = new(); -#else - private static readonly Dictionary, Delegate> CreateInstanceDelegate10Cache = new(); -#endif - public static object CreateInstance( - this Type t, - TArg1 arg1, - TArg2 arg2, - TArg3 arg3, - TArg4 arg4, - TArg5 arg5, - TArg6 arg6, - TArg7 arg7, - TArg8 arg8, - TArg9 arg9, - TArg10 arg10) + internal static readonly Dictionary CreateInstanceDelegate10Cache = new(); + public static object CreateInstance(this Type t, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8, TArg9 arg9, TArg10 arg10) { -#if NET5_0_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NET47 || NET471 || NET472 - var key = ( - t, - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4), - typeof(TArg5), - typeof(TArg6), - typeof(TArg7), - typeof(TArg8), - typeof(TArg9), - typeof(TArg10) - ); -#else - var key = Tuple.Create( - t, - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4), - typeof(TArg5), - typeof(TArg6), - typeof(TArg7), - typeof(TArg8), - typeof(TArg9), - typeof(TArg10) - ); -#endif + var key = new InstanceCacheKey(t, new[]{typeof(TArg1), typeof(TArg2), typeof(TArg3), typeof(TArg4), typeof(TArg5), typeof(TArg6), typeof(TArg7), typeof(TArg8), typeof(TArg9), typeof(TArg10)}); if (CreateInstanceDelegate10Cache.TryGetValue(key, out var del)) - return del.DynamicInvoke(arg1, - arg2, - arg3, - arg4, - arg5, - arg6, - arg7, - arg8, - arg9, - arg10 - ) + return del.DynamicInvoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10) ?? throw new NullReferenceException("Constructor yielded null result."); - var constructor = t.GetConstructor(new[] { - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4), - typeof(TArg5), - typeof(TArg6), - typeof(TArg7), - typeof(TArg8), - typeof(TArg9), - typeof(TArg10) - }); + var constructor = t.GetConstructor(new[] {typeof(TArg1), typeof(TArg2), typeof(TArg3), typeof(TArg4), typeof(TArg5), typeof(TArg6), typeof(TArg7), typeof(TArg8), typeof(TArg9), typeof(TArg10)}); if (constructor == null) { var ex = new InvalidOperationException("No matching constructor existing."); @@ -974,109 +457,14 @@ public static object CreateInstance CreateInstanceDelegate11Cache = new(); -#else - private static readonly Dictionary, Delegate> CreateInstanceDelegate11Cache = new(); -#endif - public static object CreateInstance( - this Type t, - TArg1 arg1, - TArg2 arg2, - TArg3 arg3, - TArg4 arg4, - TArg5 arg5, - TArg6 arg6, - TArg7 arg7, - TArg8 arg8, - TArg9 arg9, - TArg10 arg10, - TArg11 arg11) + internal static readonly Dictionary CreateInstanceDelegate11Cache = new(); + public static object CreateInstance(this Type t, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8, TArg9 arg9, TArg10 arg10, TArg11 arg11) { -#if NET5_0_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NET47 || NET471 || NET472 - var key = ( - t, - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4), - typeof(TArg5), - typeof(TArg6), - typeof(TArg7), - typeof(TArg8), - typeof(TArg9), - typeof(TArg10), - typeof(TArg11) - ); -#else - var key = Tuple.Create( - t, - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4), - typeof(TArg5), - typeof(TArg6), - typeof(TArg7), - typeof(TArg8), - typeof(TArg9), - typeof(TArg10), - typeof(TArg11) - ); -#endif + var key = new InstanceCacheKey(t, new[]{typeof(TArg1), typeof(TArg2), typeof(TArg3), typeof(TArg4), typeof(TArg5), typeof(TArg6), typeof(TArg7), typeof(TArg8), typeof(TArg9), typeof(TArg10), typeof(TArg11)}); if (CreateInstanceDelegate11Cache.TryGetValue(key, out var del)) - return del.DynamicInvoke(arg1, - arg2, - arg3, - arg4, - arg5, - arg6, - arg7, - arg8, - arg9, - arg10, - arg11 - ) + return del.DynamicInvoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11) ?? throw new NullReferenceException("Constructor yielded null result."); - var constructor = t.GetConstructor(new[] { - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4), - typeof(TArg5), - typeof(TArg6), - typeof(TArg7), - typeof(TArg8), - typeof(TArg9), - typeof(TArg10), - typeof(TArg11) - }); + var constructor = t.GetConstructor(new[] {typeof(TArg1), typeof(TArg2), typeof(TArg3), typeof(TArg4), typeof(TArg5), typeof(TArg6), typeof(TArg7), typeof(TArg8), typeof(TArg9), typeof(TArg10), typeof(TArg11)}); if (constructor == null) { var ex = new InvalidOperationException("No matching constructor existing."); @@ -1127,116 +515,14 @@ public static object CreateInstance CreateInstanceDelegate12Cache = new(); -#else - private static readonly Dictionary, Delegate> CreateInstanceDelegate12Cache = new(); -#endif - public static object CreateInstance( - this Type t, - TArg1 arg1, - TArg2 arg2, - TArg3 arg3, - TArg4 arg4, - TArg5 arg5, - TArg6 arg6, - TArg7 arg7, - TArg8 arg8, - TArg9 arg9, - TArg10 arg10, - TArg11 arg11, - TArg12 arg12) + internal static readonly Dictionary CreateInstanceDelegate12Cache = new(); + public static object CreateInstance(this Type t, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8, TArg9 arg9, TArg10 arg10, TArg11 arg11, TArg12 arg12) { -#if NET5_0_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NET47 || NET471 || NET472 - var key = ( - t, - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4), - typeof(TArg5), - typeof(TArg6), - typeof(TArg7), - typeof(TArg8), - typeof(TArg9), - typeof(TArg10), - typeof(TArg11), - typeof(TArg12) - ); -#else - var key = Tuple.Create( - t, - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4), - typeof(TArg5), - typeof(TArg6), - typeof(TArg7), - typeof(TArg8), - typeof(TArg9), - typeof(TArg10), - typeof(TArg11), - typeof(TArg12) - ); -#endif + var key = new InstanceCacheKey(t, new[]{typeof(TArg1), typeof(TArg2), typeof(TArg3), typeof(TArg4), typeof(TArg5), typeof(TArg6), typeof(TArg7), typeof(TArg8), typeof(TArg9), typeof(TArg10), typeof(TArg11), typeof(TArg12)}); if (CreateInstanceDelegate12Cache.TryGetValue(key, out var del)) - return del.DynamicInvoke(arg1, - arg2, - arg3, - arg4, - arg5, - arg6, - arg7, - arg8, - arg9, - arg10, - arg11, - arg12 - ) + return del.DynamicInvoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12) ?? throw new NullReferenceException("Constructor yielded null result."); - var constructor = t.GetConstructor(new[] { - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4), - typeof(TArg5), - typeof(TArg6), - typeof(TArg7), - typeof(TArg8), - typeof(TArg9), - typeof(TArg10), - typeof(TArg11), - typeof(TArg12) - }); + var constructor = t.GetConstructor(new[] {typeof(TArg1), typeof(TArg2), typeof(TArg3), typeof(TArg4), typeof(TArg5), typeof(TArg6), typeof(TArg7), typeof(TArg8), typeof(TArg9), typeof(TArg10), typeof(TArg11), typeof(TArg12)}); if (constructor == null) { var ex = new InvalidOperationException("No matching constructor existing."); @@ -1290,123 +576,14 @@ public static object CreateInstance CreateInstanceDelegate13Cache = new(); -#else - private static readonly Dictionary, Delegate> CreateInstanceDelegate13Cache = new(); -#endif - public static object CreateInstance( - this Type t, - TArg1 arg1, - TArg2 arg2, - TArg3 arg3, - TArg4 arg4, - TArg5 arg5, - TArg6 arg6, - TArg7 arg7, - TArg8 arg8, - TArg9 arg9, - TArg10 arg10, - TArg11 arg11, - TArg12 arg12, - TArg13 arg13) + internal static readonly Dictionary CreateInstanceDelegate13Cache = new(); + public static object CreateInstance(this Type t, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8, TArg9 arg9, TArg10 arg10, TArg11 arg11, TArg12 arg12, TArg13 arg13) { -#if NET5_0_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NET47 || NET471 || NET472 - var key = ( - t, - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4), - typeof(TArg5), - typeof(TArg6), - typeof(TArg7), - typeof(TArg8), - typeof(TArg9), - typeof(TArg10), - typeof(TArg11), - typeof(TArg12), - typeof(TArg13) - ); -#else - var key = Tuple.Create( - t, - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4), - typeof(TArg5), - typeof(TArg6), - typeof(TArg7), - typeof(TArg8), - typeof(TArg9), - typeof(TArg10), - typeof(TArg11), - typeof(TArg12), - typeof(TArg13) - ); -#endif + var key = new InstanceCacheKey(t, new[]{typeof(TArg1), typeof(TArg2), typeof(TArg3), typeof(TArg4), typeof(TArg5), typeof(TArg6), typeof(TArg7), typeof(TArg8), typeof(TArg9), typeof(TArg10), typeof(TArg11), typeof(TArg12), typeof(TArg13)}); if (CreateInstanceDelegate13Cache.TryGetValue(key, out var del)) - return del.DynamicInvoke(arg1, - arg2, - arg3, - arg4, - arg5, - arg6, - arg7, - arg8, - arg9, - arg10, - arg11, - arg12, - arg13 - ) + return del.DynamicInvoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13) ?? throw new NullReferenceException("Constructor yielded null result."); - var constructor = t.GetConstructor(new[] { - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4), - typeof(TArg5), - typeof(TArg6), - typeof(TArg7), - typeof(TArg8), - typeof(TArg9), - typeof(TArg10), - typeof(TArg11), - typeof(TArg12), - typeof(TArg13) - }); + var constructor = t.GetConstructor(new[] {typeof(TArg1), typeof(TArg2), typeof(TArg3), typeof(TArg4), typeof(TArg5), typeof(TArg6), typeof(TArg7), typeof(TArg8), typeof(TArg9), typeof(TArg10), typeof(TArg11), typeof(TArg12), typeof(TArg13)}); if (constructor == null) { var ex = new InvalidOperationException("No matching constructor existing."); @@ -1463,130 +640,14 @@ public static object CreateInstance CreateInstanceDelegate14Cache = new(); -#else - private static readonly Dictionary, Delegate> CreateInstanceDelegate14Cache = new(); -#endif - public static object CreateInstance( - this Type t, - TArg1 arg1, - TArg2 arg2, - TArg3 arg3, - TArg4 arg4, - TArg5 arg5, - TArg6 arg6, - TArg7 arg7, - TArg8 arg8, - TArg9 arg9, - TArg10 arg10, - TArg11 arg11, - TArg12 arg12, - TArg13 arg13, - TArg14 arg14) + internal static readonly Dictionary CreateInstanceDelegate14Cache = new(); + public static object CreateInstance(this Type t, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8, TArg9 arg9, TArg10 arg10, TArg11 arg11, TArg12 arg12, TArg13 arg13, TArg14 arg14) { -#if NET5_0_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NET47 || NET471 || NET472 - var key = ( - t, - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4), - typeof(TArg5), - typeof(TArg6), - typeof(TArg7), - typeof(TArg8), - typeof(TArg9), - typeof(TArg10), - typeof(TArg11), - typeof(TArg12), - typeof(TArg13), - typeof(TArg14) - ); -#else - var key = Tuple.Create( - t, - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4), - typeof(TArg5), - typeof(TArg6), - typeof(TArg7), - typeof(TArg8), - typeof(TArg9), - typeof(TArg10), - typeof(TArg11), - typeof(TArg12), - typeof(TArg13), - typeof(TArg14) - ); -#endif + var key = new InstanceCacheKey(t, new[]{typeof(TArg1), typeof(TArg2), typeof(TArg3), typeof(TArg4), typeof(TArg5), typeof(TArg6), typeof(TArg7), typeof(TArg8), typeof(TArg9), typeof(TArg10), typeof(TArg11), typeof(TArg12), typeof(TArg13), typeof(TArg14)}); if (CreateInstanceDelegate14Cache.TryGetValue(key, out var del)) - return del.DynamicInvoke(arg1, - arg2, - arg3, - arg4, - arg5, - arg6, - arg7, - arg8, - arg9, - arg10, - arg11, - arg12, - arg13, - arg14 - ) + return del.DynamicInvoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14) ?? throw new NullReferenceException("Constructor yielded null result."); - var constructor = t.GetConstructor(new[] { - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4), - typeof(TArg5), - typeof(TArg6), - typeof(TArg7), - typeof(TArg8), - typeof(TArg9), - typeof(TArg10), - typeof(TArg11), - typeof(TArg12), - typeof(TArg13), - typeof(TArg14) - }); + var constructor = t.GetConstructor(new[] {typeof(TArg1), typeof(TArg2), typeof(TArg3), typeof(TArg4), typeof(TArg5), typeof(TArg6), typeof(TArg7), typeof(TArg8), typeof(TArg9), typeof(TArg10), typeof(TArg11), typeof(TArg12), typeof(TArg13), typeof(TArg14)}); if (constructor == null) { var ex = new InvalidOperationException("No matching constructor existing."); @@ -1646,137 +707,14 @@ public static object CreateInstance CreateInstanceDelegate15Cache = new(); -#else - private static readonly Dictionary, Delegate> CreateInstanceDelegate15Cache = new(); -#endif - public static object CreateInstance( - this Type t, - TArg1 arg1, - TArg2 arg2, - TArg3 arg3, - TArg4 arg4, - TArg5 arg5, - TArg6 arg6, - TArg7 arg7, - TArg8 arg8, - TArg9 arg9, - TArg10 arg10, - TArg11 arg11, - TArg12 arg12, - TArg13 arg13, - TArg14 arg14, - TArg15 arg15) + internal static readonly Dictionary CreateInstanceDelegate15Cache = new(); + public static object CreateInstance(this Type t, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8, TArg9 arg9, TArg10 arg10, TArg11 arg11, TArg12 arg12, TArg13 arg13, TArg14 arg14, TArg15 arg15) { -#if NET5_0_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NET47 || NET471 || NET472 - var key = ( - t, - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4), - typeof(TArg5), - typeof(TArg6), - typeof(TArg7), - typeof(TArg8), - typeof(TArg9), - typeof(TArg10), - typeof(TArg11), - typeof(TArg12), - typeof(TArg13), - typeof(TArg14), - typeof(TArg15) - ); -#else - var key = Tuple.Create( - t, - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4), - typeof(TArg5), - typeof(TArg6), - typeof(TArg7), - typeof(TArg8), - typeof(TArg9), - typeof(TArg10), - typeof(TArg11), - typeof(TArg12), - typeof(TArg13), - typeof(TArg14), - typeof(TArg15) - ); -#endif + var key = new InstanceCacheKey(t, new[]{typeof(TArg1), typeof(TArg2), typeof(TArg3), typeof(TArg4), typeof(TArg5), typeof(TArg6), typeof(TArg7), typeof(TArg8), typeof(TArg9), typeof(TArg10), typeof(TArg11), typeof(TArg12), typeof(TArg13), typeof(TArg14), typeof(TArg15)}); if (CreateInstanceDelegate15Cache.TryGetValue(key, out var del)) - return del.DynamicInvoke(arg1, - arg2, - arg3, - arg4, - arg5, - arg6, - arg7, - arg8, - arg9, - arg10, - arg11, - arg12, - arg13, - arg14, - arg15 - ) + return del.DynamicInvoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15) ?? throw new NullReferenceException("Constructor yielded null result."); - var constructor = t.GetConstructor(new[] { - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4), - typeof(TArg5), - typeof(TArg6), - typeof(TArg7), - typeof(TArg8), - typeof(TArg9), - typeof(TArg10), - typeof(TArg11), - typeof(TArg12), - typeof(TArg13), - typeof(TArg14), - typeof(TArg15) - }); + var constructor = t.GetConstructor(new[] {typeof(TArg1), typeof(TArg2), typeof(TArg3), typeof(TArg4), typeof(TArg5), typeof(TArg6), typeof(TArg7), typeof(TArg8), typeof(TArg9), typeof(TArg10), typeof(TArg11), typeof(TArg12), typeof(TArg13), typeof(TArg14), typeof(TArg15)}); if (constructor == null) { var ex = new InvalidOperationException("No matching constructor existing."); @@ -1839,144 +777,14 @@ public static object CreateInstance CreateInstanceDelegate16Cache = new(); -#else - private static readonly Dictionary, Delegate> CreateInstanceDelegate16Cache = new(); -#endif - public static object CreateInstance( - this Type t, - TArg1 arg1, - TArg2 arg2, - TArg3 arg3, - TArg4 arg4, - TArg5 arg5, - TArg6 arg6, - TArg7 arg7, - TArg8 arg8, - TArg9 arg9, - TArg10 arg10, - TArg11 arg11, - TArg12 arg12, - TArg13 arg13, - TArg14 arg14, - TArg15 arg15, - TArg16 arg16) + internal static readonly Dictionary CreateInstanceDelegate16Cache = new(); + public static object CreateInstance(this Type t, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8, TArg9 arg9, TArg10 arg10, TArg11 arg11, TArg12 arg12, TArg13 arg13, TArg14 arg14, TArg15 arg15, TArg16 arg16) { -#if NET5_0_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NET47 || NET471 || NET472 - var key = ( - t, - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4), - typeof(TArg5), - typeof(TArg6), - typeof(TArg7), - typeof(TArg8), - typeof(TArg9), - typeof(TArg10), - typeof(TArg11), - typeof(TArg12), - typeof(TArg13), - typeof(TArg14), - typeof(TArg15), - typeof(TArg16) - ); -#else - var key = Tuple.Create( - t, - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4), - typeof(TArg5), - typeof(TArg6), - typeof(TArg7), - typeof(TArg8), - typeof(TArg9), - typeof(TArg10), - typeof(TArg11), - typeof(TArg12), - typeof(TArg13), - typeof(TArg14), - typeof(TArg15), - typeof(TArg16) - ); -#endif + var key = new InstanceCacheKey(t, new[]{typeof(TArg1), typeof(TArg2), typeof(TArg3), typeof(TArg4), typeof(TArg5), typeof(TArg6), typeof(TArg7), typeof(TArg8), typeof(TArg9), typeof(TArg10), typeof(TArg11), typeof(TArg12), typeof(TArg13), typeof(TArg14), typeof(TArg15), typeof(TArg16)}); if (CreateInstanceDelegate16Cache.TryGetValue(key, out var del)) - return del.DynamicInvoke(arg1, - arg2, - arg3, - arg4, - arg5, - arg6, - arg7, - arg8, - arg9, - arg10, - arg11, - arg12, - arg13, - arg14, - arg15, - arg16 - ) + return del.DynamicInvoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16) ?? throw new NullReferenceException("Constructor yielded null result."); - var constructor = t.GetConstructor(new[] { - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4), - typeof(TArg5), - typeof(TArg6), - typeof(TArg7), - typeof(TArg8), - typeof(TArg9), - typeof(TArg10), - typeof(TArg11), - typeof(TArg12), - typeof(TArg13), - typeof(TArg14), - typeof(TArg15), - typeof(TArg16) - }); + var constructor = t.GetConstructor(new[] {typeof(TArg1), typeof(TArg2), typeof(TArg3), typeof(TArg4), typeof(TArg5), typeof(TArg6), typeof(TArg7), typeof(TArg8), typeof(TArg9), typeof(TArg10), typeof(TArg11), typeof(TArg12), typeof(TArg13), typeof(TArg14), typeof(TArg15), typeof(TArg16)}); if (constructor == null) { var ex = new InvalidOperationException("No matching constructor existing."); @@ -2042,151 +850,14 @@ public static object CreateInstance CreateInstanceDelegate17Cache = new(); -#else - private static readonly Dictionary, Delegate> CreateInstanceDelegate17Cache = new(); -#endif - public static object CreateInstance( - this Type t, - TArg1 arg1, - TArg2 arg2, - TArg3 arg3, - TArg4 arg4, - TArg5 arg5, - TArg6 arg6, - TArg7 arg7, - TArg8 arg8, - TArg9 arg9, - TArg10 arg10, - TArg11 arg11, - TArg12 arg12, - TArg13 arg13, - TArg14 arg14, - TArg15 arg15, - TArg16 arg16, - TArg17 arg17) + internal static readonly Dictionary CreateInstanceDelegate17Cache = new(); + public static object CreateInstance(this Type t, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8, TArg9 arg9, TArg10 arg10, TArg11 arg11, TArg12 arg12, TArg13 arg13, TArg14 arg14, TArg15 arg15, TArg16 arg16, TArg17 arg17) { -#if NET5_0_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NET47 || NET471 || NET472 - var key = ( - t, - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4), - typeof(TArg5), - typeof(TArg6), - typeof(TArg7), - typeof(TArg8), - typeof(TArg9), - typeof(TArg10), - typeof(TArg11), - typeof(TArg12), - typeof(TArg13), - typeof(TArg14), - typeof(TArg15), - typeof(TArg16), - typeof(TArg17) - ); -#else - var key = Tuple.Create( - t, - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4), - typeof(TArg5), - typeof(TArg6), - typeof(TArg7), - typeof(TArg8), - typeof(TArg9), - typeof(TArg10), - typeof(TArg11), - typeof(TArg12), - typeof(TArg13), - typeof(TArg14), - typeof(TArg15), - typeof(TArg16), - typeof(TArg17) - ); -#endif + var key = new InstanceCacheKey(t, new[]{typeof(TArg1), typeof(TArg2), typeof(TArg3), typeof(TArg4), typeof(TArg5), typeof(TArg6), typeof(TArg7), typeof(TArg8), typeof(TArg9), typeof(TArg10), typeof(TArg11), typeof(TArg12), typeof(TArg13), typeof(TArg14), typeof(TArg15), typeof(TArg16), typeof(TArg17)}); if (CreateInstanceDelegate17Cache.TryGetValue(key, out var del)) - return del.DynamicInvoke(arg1, - arg2, - arg3, - arg4, - arg5, - arg6, - arg7, - arg8, - arg9, - arg10, - arg11, - arg12, - arg13, - arg14, - arg15, - arg16, - arg17 - ) + return del.DynamicInvoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17) ?? throw new NullReferenceException("Constructor yielded null result."); - var constructor = t.GetConstructor(new[] { - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4), - typeof(TArg5), - typeof(TArg6), - typeof(TArg7), - typeof(TArg8), - typeof(TArg9), - typeof(TArg10), - typeof(TArg11), - typeof(TArg12), - typeof(TArg13), - typeof(TArg14), - typeof(TArg15), - typeof(TArg16), - typeof(TArg17) - }); + var constructor = t.GetConstructor(new[] {typeof(TArg1), typeof(TArg2), typeof(TArg3), typeof(TArg4), typeof(TArg5), typeof(TArg6), typeof(TArg7), typeof(TArg8), typeof(TArg9), typeof(TArg10), typeof(TArg11), typeof(TArg12), typeof(TArg13), typeof(TArg14), typeof(TArg15), typeof(TArg16), typeof(TArg17)}); if (constructor == null) { var ex = new InvalidOperationException("No matching constructor existing."); @@ -2255,158 +926,14 @@ public static object CreateInstance CreateInstanceDelegate18Cache = new(); -#else - private static readonly Dictionary, Delegate> CreateInstanceDelegate18Cache = new(); -#endif - public static object CreateInstance( - this Type t, - TArg1 arg1, - TArg2 arg2, - TArg3 arg3, - TArg4 arg4, - TArg5 arg5, - TArg6 arg6, - TArg7 arg7, - TArg8 arg8, - TArg9 arg9, - TArg10 arg10, - TArg11 arg11, - TArg12 arg12, - TArg13 arg13, - TArg14 arg14, - TArg15 arg15, - TArg16 arg16, - TArg17 arg17, - TArg18 arg18) + internal static readonly Dictionary CreateInstanceDelegate18Cache = new(); + public static object CreateInstance(this Type t, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8, TArg9 arg9, TArg10 arg10, TArg11 arg11, TArg12 arg12, TArg13 arg13, TArg14 arg14, TArg15 arg15, TArg16 arg16, TArg17 arg17, TArg18 arg18) { -#if NET5_0_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NET47 || NET471 || NET472 - var key = ( - t, - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4), - typeof(TArg5), - typeof(TArg6), - typeof(TArg7), - typeof(TArg8), - typeof(TArg9), - typeof(TArg10), - typeof(TArg11), - typeof(TArg12), - typeof(TArg13), - typeof(TArg14), - typeof(TArg15), - typeof(TArg16), - typeof(TArg17), - typeof(TArg18) - ); -#else - var key = Tuple.Create( - t, - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4), - typeof(TArg5), - typeof(TArg6), - typeof(TArg7), - typeof(TArg8), - typeof(TArg9), - typeof(TArg10), - typeof(TArg11), - typeof(TArg12), - typeof(TArg13), - typeof(TArg14), - typeof(TArg15), - typeof(TArg16), - typeof(TArg17), - typeof(TArg18) - ); -#endif + var key = new InstanceCacheKey(t, new[]{typeof(TArg1), typeof(TArg2), typeof(TArg3), typeof(TArg4), typeof(TArg5), typeof(TArg6), typeof(TArg7), typeof(TArg8), typeof(TArg9), typeof(TArg10), typeof(TArg11), typeof(TArg12), typeof(TArg13), typeof(TArg14), typeof(TArg15), typeof(TArg16), typeof(TArg17), typeof(TArg18)}); if (CreateInstanceDelegate18Cache.TryGetValue(key, out var del)) - return del.DynamicInvoke(arg1, - arg2, - arg3, - arg4, - arg5, - arg6, - arg7, - arg8, - arg9, - arg10, - arg11, - arg12, - arg13, - arg14, - arg15, - arg16, - arg17, - arg18 - ) + return del.DynamicInvoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18) ?? throw new NullReferenceException("Constructor yielded null result."); - var constructor = t.GetConstructor(new[] { - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4), - typeof(TArg5), - typeof(TArg6), - typeof(TArg7), - typeof(TArg8), - typeof(TArg9), - typeof(TArg10), - typeof(TArg11), - typeof(TArg12), - typeof(TArg13), - typeof(TArg14), - typeof(TArg15), - typeof(TArg16), - typeof(TArg17), - typeof(TArg18) - }); + var constructor = t.GetConstructor(new[] {typeof(TArg1), typeof(TArg2), typeof(TArg3), typeof(TArg4), typeof(TArg5), typeof(TArg6), typeof(TArg7), typeof(TArg8), typeof(TArg9), typeof(TArg10), typeof(TArg11), typeof(TArg12), typeof(TArg13), typeof(TArg14), typeof(TArg15), typeof(TArg16), typeof(TArg17), typeof(TArg18)}); if (constructor == null) { var ex = new InvalidOperationException("No matching constructor existing."); @@ -2478,165 +1005,14 @@ public static object CreateInstance CreateInstanceDelegate19Cache = new(); -#else - private static readonly Dictionary, Delegate> CreateInstanceDelegate19Cache = new(); -#endif - public static object CreateInstance( - this Type t, - TArg1 arg1, - TArg2 arg2, - TArg3 arg3, - TArg4 arg4, - TArg5 arg5, - TArg6 arg6, - TArg7 arg7, - TArg8 arg8, - TArg9 arg9, - TArg10 arg10, - TArg11 arg11, - TArg12 arg12, - TArg13 arg13, - TArg14 arg14, - TArg15 arg15, - TArg16 arg16, - TArg17 arg17, - TArg18 arg18, - TArg19 arg19) + internal static readonly Dictionary CreateInstanceDelegate19Cache = new(); + public static object CreateInstance(this Type t, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8, TArg9 arg9, TArg10 arg10, TArg11 arg11, TArg12 arg12, TArg13 arg13, TArg14 arg14, TArg15 arg15, TArg16 arg16, TArg17 arg17, TArg18 arg18, TArg19 arg19) { -#if NET5_0_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NET47 || NET471 || NET472 - var key = ( - t, - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4), - typeof(TArg5), - typeof(TArg6), - typeof(TArg7), - typeof(TArg8), - typeof(TArg9), - typeof(TArg10), - typeof(TArg11), - typeof(TArg12), - typeof(TArg13), - typeof(TArg14), - typeof(TArg15), - typeof(TArg16), - typeof(TArg17), - typeof(TArg18), - typeof(TArg19) - ); -#else - var key = Tuple.Create( - t, - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4), - typeof(TArg5), - typeof(TArg6), - typeof(TArg7), - typeof(TArg8), - typeof(TArg9), - typeof(TArg10), - typeof(TArg11), - typeof(TArg12), - typeof(TArg13), - typeof(TArg14), - typeof(TArg15), - typeof(TArg16), - typeof(TArg17), - typeof(TArg18), - typeof(TArg19) - ); -#endif + var key = new InstanceCacheKey(t, new[]{typeof(TArg1), typeof(TArg2), typeof(TArg3), typeof(TArg4), typeof(TArg5), typeof(TArg6), typeof(TArg7), typeof(TArg8), typeof(TArg9), typeof(TArg10), typeof(TArg11), typeof(TArg12), typeof(TArg13), typeof(TArg14), typeof(TArg15), typeof(TArg16), typeof(TArg17), typeof(TArg18), typeof(TArg19)}); if (CreateInstanceDelegate19Cache.TryGetValue(key, out var del)) - return del.DynamicInvoke(arg1, - arg2, - arg3, - arg4, - arg5, - arg6, - arg7, - arg8, - arg9, - arg10, - arg11, - arg12, - arg13, - arg14, - arg15, - arg16, - arg17, - arg18, - arg19 - ) + return del.DynamicInvoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19) ?? throw new NullReferenceException("Constructor yielded null result."); - var constructor = t.GetConstructor(new[] { - typeof(TArg1), - typeof(TArg2), - typeof(TArg3), - typeof(TArg4), - typeof(TArg5), - typeof(TArg6), - typeof(TArg7), - typeof(TArg8), - typeof(TArg9), - typeof(TArg10), - typeof(TArg11), - typeof(TArg12), - typeof(TArg13), - typeof(TArg14), - typeof(TArg15), - typeof(TArg16), - typeof(TArg17), - typeof(TArg18), - typeof(TArg19) - }); + var constructor = t.GetConstructor(new[] {typeof(TArg1), typeof(TArg2), typeof(TArg3), typeof(TArg4), typeof(TArg5), typeof(TArg6), typeof(TArg7), typeof(TArg8), typeof(TArg9), typeof(TArg10), typeof(TArg11), typeof(TArg12), typeof(TArg13), typeof(TArg14), typeof(TArg15), typeof(TArg16), typeof(TArg17), typeof(TArg18), typeof(TArg19)}); if (constructor == null) { var ex = new InvalidOperationException("No matching constructor existing."); diff --git a/X39.Util/TypeExtensions.t4.tt b/X39.Util/TypeExtensions.t4.tt index e74b9fe..fa61f7c 100644 --- a/X39.Util/TypeExtensions.t4.tt +++ b/X39.Util/TypeExtensions.t4.tt @@ -2,15 +2,20 @@ <#@ output extension=".cs" #> <#@ Assembly Name="System.Core, Version=4.0.0.0, Culture=neutral" #> <#@ Assembly Name="Microsoft.CSharp, Version=4.0.0.0, Culture=neutral" #> +<#@ import namespace="System.Linq" #> using System.Linq.Expressions; namespace X39.Util; public static partial class TypeExtensionMethods { + private static void ClearDynCache() + { <# for (var i = 1; i < 20; i++) { +#> +<# if (i >= 7) { #> @@ -18,79 +23,44 @@ public static partial class TypeExtensionMethods <# } #> - -#if NET5_0_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NET47 || NET471 || NET472 - private static readonly Dictionary<( - Type, - <# - for (var j = 1; j <= i; j++) - { - Write($"Type"); - Write(j != i ? ",\r\n " : "\r\n "); - } -#>), Delegate> CreateInstanceDelegate<#= i #>Cache = new(); -#else - private static readonly DictionaryCache.Clear(); +<# + if (i >= 7) { - Write($"Type"); - Write(j != i ? ",\r\n " : "\r\n "); - } -#>>, Delegate> CreateInstanceDelegate<#= i #>Cache = new(); +#> #endif - public static object CreateInstance<<# - for (var j = 1; j <= i; j++) - { - Write(j != i ? $"TArg{j}, " : $"TArg{j}"); - } -#>>( - this Type t<# - for (var j = 1; j <= i; j++) - { - Write($",\r\n TArg{j} arg{j}"); +<# } -#>) +#> +<# + } +#> + } +<# + for (var i = 1; i < 20; i++) { -#if NET5_0_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NET47 || NET471 || NET472 - var key = ( - t, - <# - for (var j = 1; j <= i; j++) - { - Write($"typeof(TArg{j})"); - Write(j != i ? ",\r\n " : "\r\n "); - } -#>); -#else - var key = Tuple.Create( - t, - <# - for (var j = 1; j <= i; j++) + var argList = string.Join(", ", Enumerable.Range(0, i).Select((q) => string.Concat("TArg", q + 1))); + var valueList = string.Join(", ", Enumerable.Range(0, i).Select((q) => string.Concat("arg", q + 1))); + var paramList = string.Join(", ", + Enumerable.Range(0, i).Select((q) => string.Concat("TArg", q + 1, " arg", q + 1))); + var typeOfArgList = string.Join(", ", + Enumerable.Range(0, i).Select((q) => string.Concat("typeof(TArg", q + 1, ")"))); + if (i >= 7) { - Write($"typeof(TArg{j})"); - Write(j != i ? ",\r\n " : "\r\n "); +#> +#if NET5_0_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NET47 || NET471 || NET472 +<# } -#>); -#endif +#> + + internal static readonly Dictionary CreateInstanceDelegate<#= i #>Cache = new(); + public static object CreateInstance<<#= argList #>>(this Type t<#= i > 0 ? ", " : string.Empty #><#= paramList #>) + { + var key = new InstanceCacheKey(t, new[]{<#= typeOfArgList #>}); if (CreateInstanceDelegate<#= i #>Cache.TryGetValue(key, out var del)) - return del.DynamicInvoke(<# - for (var j = 1; j <= i; j++) - { - Write($"arg{j}"); - Write(j != i ? ",\r\n " : "\r\n "); - } -#>) + return del.DynamicInvoke(<#= valueList #>) ?? throw new NullReferenceException("Constructor yielded null result."); - var constructor = t.GetConstructor(new[] { - <# - for (var j = 1; j <= i; j++) - { - Write($"typeof(TArg{j})"); - Write(j != i ? ",\r\n " : "\r\n "); - } -#>}); + var constructor = t.GetConstructor(new[] {<#= typeOfArgList #>}); if (constructor == null) { var ex = new InvalidOperationException("No matching constructor existing."); diff --git a/X39.Util/X39.Util.csproj b/X39.Util/X39.Util.csproj index 1c8c245..d26c58d 100644 --- a/X39.Util/X39.Util.csproj +++ b/X39.Util/X39.Util.csproj @@ -27,6 +27,7 @@ + True \ @@ -57,11 +58,6 @@ - - True - True - TypeExtensions.t4.tt - True True @@ -73,6 +69,11 @@ Fault.t4.tt + + True + True + TypeExtensions.t4.tt +