com.wallstop-studios.unity-helpers 2.0.0-rc79.4 → 2.0.0-rc79.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/.github/dependabot.yml +5 -1
  2. package/.github/workflows/npm-publish.yml +2 -2
  3. package/Runtime/Core/Extension/EnumExtensions.cs +1 -1
  4. package/Runtime/Core/Extension/IReadonlyListExtensions.cs +1 -1
  5. package/Runtime/Core/Extension/IReadonlyListExtensions.cs.meta +1 -1
  6. package/Runtime/Core/Extension/StringExtensions.cs +1 -1
  7. package/Runtime/Core/Helper/ReflectionHelpers.cs +1368 -22
  8. package/Runtime/Core/Helper/StringInList.cs +3 -21
  9. package/Runtime/Core/Threading/SingleThreadedThreadPool.cs +157 -49
  10. package/Runtime/Utils/Buffers.cs +2 -2
  11. package/Runtime/Utils/SevenZip/Common/CRC.cs +9 -0
  12. package/Runtime/Utils/SevenZip/Common/InBuffer.cs +15 -2
  13. package/Runtime/Utils/SevenZip/Common/OutBuffer.cs +7 -2
  14. package/Runtime/Utils/SevenZip/Compress/LZ/LzBinTree.cs +50 -0
  15. package/Runtime/Utils/SevenZip/Compress/LZ/LzInWindow.cs +26 -0
  16. package/Runtime/Utils/SevenZip/Compress/LZ/LzOutWindow.cs +27 -0
  17. package/Runtime/Utils/SevenZip/Compress/LZMA/LzmaBase.cs +9 -0
  18. package/Runtime/Utils/SevenZip/Compress/LZMA/LzmaDecoder.cs +80 -17
  19. package/Runtime/Utils/SevenZip/Compress/LZMA/LzmaEncoder.cs +265 -30
  20. package/Runtime/Utils/SevenZip/Compress/RangeCoder/RangeCoder.cs +9 -0
  21. package/Runtime/Utils/SevenZip/Compress/RangeCoder/RangeCoderBit.cs +13 -1
  22. package/Runtime/Utils/SevenZip/Compress/RangeCoder/RangeCoderBitTree.cs +11 -4
  23. package/Tests/Runtime/Core/Threading/SingleThreadedThreadPoolTests.cs +54 -0
  24. package/Tests/Runtime/Core/Threading/SingleThreadedThreadPoolTests.cs.meta +3 -0
  25. package/Tests/Runtime/Core/Threading.meta +3 -0
  26. package/Tests/Runtime/Core.meta +3 -0
  27. package/Tests/Runtime/DataStructures/BalancedKDTreeTests.cs +1 -1
  28. package/Tests/Runtime/DataStructures/CyclicBufferTests.cs +1 -1
  29. package/Tests/Runtime/DataStructures/QuadTreeTests.cs +1 -1
  30. package/Tests/Runtime/DataStructures/SpatialTreeTests.cs +1 -1
  31. package/Tests/Runtime/DataStructures/UnbalancedKDTreeTests.cs +1 -1
  32. package/Tests/Runtime/Extensions/DictionaryExtensionTests.cs +1 -1
  33. package/Tests/Runtime/Extensions/EnumExtensionTests.cs +1 -1
  34. package/Tests/Runtime/Extensions/IListExtensionTests.cs +1 -1
  35. package/Tests/Runtime/Extensions/IReadonlyListExtensionTests.cs +1 -1
  36. package/Tests/Runtime/Extensions/IReadonlyListExtensionTests.cs.meta +1 -1
  37. package/Tests/Runtime/Extensions/LoggingExtensionTests.cs +1 -1
  38. package/Tests/Runtime/Extensions/RandomExtensionTests.cs +1 -1
  39. package/Tests/Runtime/Extensions/StringExtensionTests.cs +1 -1
  40. package/Tests/Runtime/Helper/ObjectHelperTests.cs +1 -1
  41. package/Tests/Runtime/Helper/ReflectionHelperTests.cs +961 -0
  42. package/Tests/Runtime/Helper/WallMathTests.cs +1 -1
  43. package/Tests/Runtime/Performance/KDTreePerformanceTests.cs +1 -1
  44. package/Tests/Runtime/Performance/QuadTreePerformanceTests.cs +1 -1
  45. package/Tests/Runtime/Performance/SpatialTreePerformanceTest.cs +1 -2
  46. package/Tests/Runtime/Performance/UnbalancedKDTreeTests.cs +1 -1
  47. package/Tests/Runtime/Random/RandomTestBase.cs +2 -2
  48. package/Tests/Runtime/Serialization/JsonSerializationTest.cs +1 -1
  49. package/Tests/Runtime/Utils/BuffersTests.cs +6 -6
  50. package/Tests/Runtime/Utils/BuffersTests.cs.meta +1 -1
  51. package/package.json +3 -1
@@ -1,25 +1,44 @@
1
1
  #if !((UNITY_WEBGL && !UNITY_EDITOR) || ENABLE_IL2CPP)
2
2
  #define EMIT_DYNAMIC_IL
3
+ #define SUPPORT_EXPRESSION_COMPILE
3
4
  #endif
4
5
 
5
6
  namespace WallstopStudios.UnityHelpers.Core.Helper
6
7
  {
7
8
  using System;
8
9
  using System.Collections;
10
+ using System.Collections.Concurrent;
9
11
  using System.Collections.Generic;
10
12
  using System.Linq;
13
+ using System.Linq.Expressions;
11
14
  using System.Reflection;
12
15
  using System.Reflection.Emit;
13
16
  using System.Runtime.CompilerServices;
14
- using Extension;
15
17
 
16
18
  public delegate void FieldSetter<TInstance, in TValue>(ref TInstance instance, TValue value);
17
19
 
18
20
  public static class ReflectionHelpers
19
21
  {
20
- private static readonly Dictionary<Type, Func<int, Array>> ArrayCreators = new();
21
- private static readonly Dictionary<Type, Func<IList>> ListCreators = new();
22
- private static readonly Dictionary<Type, Func<int, IList>> ListWithCapacityCreators = new();
22
+ private static readonly ConcurrentDictionary<Type, Func<int, Array>> ArrayCreators = new();
23
+ private static readonly ConcurrentDictionary<Type, Func<IList>> ListCreators = new();
24
+ private static readonly ConcurrentDictionary<
25
+ Type,
26
+ Func<int, IList>
27
+ > ListWithCapacityCreators = new();
28
+ private static readonly ConcurrentDictionary<
29
+ MethodInfo,
30
+ Func<object, object[], object>
31
+ > MethodInvokers = new();
32
+ private static readonly ConcurrentDictionary<
33
+ MethodInfo,
34
+ Func<object[], object>
35
+ > StaticMethodInvokers = new();
36
+ private static readonly ConcurrentDictionary<
37
+ ConstructorInfo,
38
+ Func<object[], object>
39
+ > Constructors = new();
40
+
41
+ private static readonly bool CanCompileExpressions = CheckExpressionCompilationSupport();
23
42
 
24
43
  public static bool IsAttributeDefined<T>(
25
44
  this ICustomAttributeProvider provider,
@@ -30,10 +49,17 @@ namespace WallstopStudios.UnityHelpers.Core.Helper
30
49
  {
31
50
  try
32
51
  {
33
- if (provider.IsDefined(typeof(T), inherit))
52
+ Type type = typeof(T);
53
+ if (provider.IsDefined(type, inherit))
34
54
  {
35
- attribute = (T)provider.GetCustomAttributes(typeof(T), inherit)[0];
36
- return true;
55
+ object[] attributes = provider.GetCustomAttributes(type, inherit);
56
+ if (attributes.Length == 0)
57
+ {
58
+ attribute = default;
59
+ return false;
60
+ }
61
+ attribute = attributes[0] as T;
62
+ return attribute != null;
37
63
  }
38
64
  }
39
65
  catch
@@ -96,7 +122,7 @@ namespace WallstopStudios.UnityHelpers.Core.Helper
96
122
  public static Func<object, object> GetFieldGetter(FieldInfo field)
97
123
  {
98
124
  #if !EMIT_DYNAMIC_IL
99
- return field.GetValue;
125
+ return CreateCompiledFieldGetter(field);
100
126
  #else
101
127
  DynamicMethod dynamicMethod = new(
102
128
  $"Get{field.DeclaringType.Name}_{field.Name}",
@@ -130,7 +156,7 @@ namespace WallstopStudios.UnityHelpers.Core.Helper
130
156
  public static Func<object, object> GetPropertyGetter(PropertyInfo property)
131
157
  {
132
158
  #if !EMIT_DYNAMIC_IL
133
- return property.GetValue;
159
+ return CreateCompiledPropertyGetter(property);
134
160
  #else
135
161
  MethodInfo getMethod = property.GetGetMethod(true);
136
162
 
@@ -143,15 +169,25 @@ namespace WallstopStudios.UnityHelpers.Core.Helper
143
169
  );
144
170
 
145
171
  ILGenerator il = dynamicMethod.GetILGenerator();
146
- il.Emit(OpCodes.Ldarg_0);
147
- il.Emit(
148
- property.DeclaringType.IsValueType ? OpCodes.Unbox : OpCodes.Castclass,
149
- property.DeclaringType
150
- );
151
- il.Emit(
152
- property.DeclaringType.IsValueType ? OpCodes.Call : OpCodes.Callvirt,
153
- getMethod
154
- );
172
+
173
+ if (getMethod.IsStatic)
174
+ {
175
+ // For static properties, don't load any arguments
176
+ il.Emit(OpCodes.Call, getMethod);
177
+ }
178
+ else
179
+ {
180
+ // For instance properties, load and cast the argument
181
+ il.Emit(OpCodes.Ldarg_0);
182
+ il.Emit(
183
+ property.DeclaringType.IsValueType ? OpCodes.Unbox : OpCodes.Castclass,
184
+ property.DeclaringType
185
+ );
186
+ il.Emit(
187
+ property.DeclaringType.IsValueType ? OpCodes.Call : OpCodes.Callvirt,
188
+ getMethod
189
+ );
190
+ }
155
191
 
156
192
  if (property.PropertyType.IsValueType)
157
193
  {
@@ -172,7 +208,7 @@ namespace WallstopStudios.UnityHelpers.Core.Helper
172
208
  }
173
209
 
174
210
  #if !EMIT_DYNAMIC_IL
175
- return () => field.GetValue(null);
211
+ return CreateCompiledStaticFieldGetter(field);
176
212
  #else
177
213
  DynamicMethod dynamicMethod = new(
178
214
  $"Get{field.DeclaringType.Name}_{field.Name}",
@@ -279,7 +315,7 @@ namespace WallstopStudios.UnityHelpers.Core.Helper
279
315
  // Use null for instance, null for indexer args for static properties
280
316
  return (TValue)property.GetValue(null, null);
281
317
  }
282
- #endif
318
+ #else
283
319
  DynamicMethod dynamicMethod = new(
284
320
  $"GetStatic_{property.DeclaringType.Name}_{property.Name}",
285
321
  typeof(TValue),
@@ -316,6 +352,7 @@ namespace WallstopStudios.UnityHelpers.Core.Helper
316
352
 
317
353
  il.Emit(OpCodes.Ret);
318
354
  return (Func<TValue>)dynamicMethod.CreateDelegate(typeof(Func<TValue>));
355
+ #endif
319
356
  }
320
357
 
321
358
  public static Func<TValue> GetStaticFieldGetter<TValue>(FieldInfo field)
@@ -446,7 +483,7 @@ namespace WallstopStudios.UnityHelpers.Core.Helper
446
483
  public static Action<object, object> GetFieldSetter(FieldInfo field)
447
484
  {
448
485
  #if !EMIT_DYNAMIC_IL
449
- return field.SetValue;
486
+ return CreateCompiledFieldSetter(field);
450
487
  #else
451
488
  DynamicMethod dynamicMethod = new(
452
489
  $"SetField{field.DeclaringType.Name}_{field.Name}",
@@ -483,7 +520,7 @@ namespace WallstopStudios.UnityHelpers.Core.Helper
483
520
  throw new ArgumentException(nameof(field));
484
521
  }
485
522
  #if !EMIT_DYNAMIC_IL
486
- return value => field.SetValue(null, value);
523
+ return CreateCompiledStaticFieldSetter(field);
487
524
  #else
488
525
  DynamicMethod dynamicMethod = new(
489
526
  $"SetFieldStatic{field.DeclaringType.Name}_{field.Name}",
@@ -586,5 +623,1314 @@ namespace WallstopStudios.UnityHelpers.Core.Helper
586
623
  return (Func<int, IList>)dynamicMethod.CreateDelegate(typeof(Func<int, IList>));
587
624
  #endif
588
625
  }
626
+
627
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
628
+ public static object InvokeMethod(
629
+ MethodInfo method,
630
+ object instance,
631
+ params object[] parameters
632
+ )
633
+ {
634
+ return MethodInvokers
635
+ .GetOrAdd(method, methodInfo => GetMethodInvoker(methodInfo))
636
+ .Invoke(instance, parameters);
637
+ }
638
+
639
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
640
+ public static object InvokeStaticMethod(MethodInfo method, params object[] parameters)
641
+ {
642
+ return StaticMethodInvokers
643
+ .GetOrAdd(method, methodInfo => GetStaticMethodInvoker(methodInfo))
644
+ .Invoke(parameters);
645
+ }
646
+
647
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
648
+ public static object CreateInstance(ConstructorInfo constructor, params object[] parameters)
649
+ {
650
+ return Constructors
651
+ .GetOrAdd(constructor, ctor => GetConstructor(ctor))
652
+ .Invoke(parameters);
653
+ }
654
+
655
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
656
+ public static T CreateInstance<T>(params object[] parameters)
657
+ {
658
+ Type type = typeof(T);
659
+ Type[] parameterTypes =
660
+ parameters?.Select(p => p?.GetType()).ToArray() ?? Type.EmptyTypes;
661
+ ConstructorInfo constructor = type.GetConstructor(parameterTypes);
662
+ if (constructor == null)
663
+ {
664
+ throw new ArgumentException($"No matching constructor found for type {type.Name}");
665
+ }
666
+ return (T)CreateInstance(constructor, parameters);
667
+ }
668
+
669
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
670
+ public static T CreateGenericInstance<T>(
671
+ Type genericTypeDefinition,
672
+ Type[] genericArguments,
673
+ params object[] parameters
674
+ )
675
+ {
676
+ Type constructedType = genericTypeDefinition.MakeGenericType(genericArguments);
677
+ Type[] parameterTypes =
678
+ parameters?.Select(p => p?.GetType()).ToArray() ?? Type.EmptyTypes;
679
+ ConstructorInfo constructor = constructedType.GetConstructor(parameterTypes);
680
+ if (constructor == null)
681
+ {
682
+ throw new ArgumentException(
683
+ $"No matching constructor found for type {constructedType.Name}"
684
+ );
685
+ }
686
+ return (T)CreateInstance(constructor, parameters);
687
+ }
688
+
689
+ public static Func<object, object[], object> GetMethodInvoker(MethodInfo method)
690
+ {
691
+ if (method.IsStatic)
692
+ {
693
+ throw new ArgumentException(
694
+ "Use GetStaticMethodInvoker for static methods",
695
+ nameof(method)
696
+ );
697
+ }
698
+
699
+ #if !EMIT_DYNAMIC_IL
700
+ return CreateCompiledMethodInvoker(method);
701
+ #else
702
+ DynamicMethod dynamicMethod = new(
703
+ $"Invoke{method.DeclaringType.Name}_{method.Name}",
704
+ typeof(object),
705
+ new[] { typeof(object), typeof(object[]) },
706
+ method.DeclaringType,
707
+ true
708
+ );
709
+
710
+ ILGenerator il = dynamicMethod.GetILGenerator();
711
+ ParameterInfo[] parameters = method.GetParameters();
712
+
713
+ il.Emit(OpCodes.Ldarg_0);
714
+ il.Emit(
715
+ method.DeclaringType.IsValueType ? OpCodes.Unbox : OpCodes.Castclass,
716
+ method.DeclaringType
717
+ );
718
+
719
+ for (int i = 0; i < parameters.Length; i++)
720
+ {
721
+ il.Emit(OpCodes.Ldarg_1);
722
+ il.Emit(OpCodes.Ldc_I4, i);
723
+ il.Emit(OpCodes.Ldelem_Ref);
724
+
725
+ Type paramType = parameters[i].ParameterType;
726
+ if (paramType.IsValueType)
727
+ {
728
+ il.Emit(OpCodes.Unbox_Any, paramType);
729
+ }
730
+ else
731
+ {
732
+ il.Emit(OpCodes.Castclass, paramType);
733
+ }
734
+ }
735
+
736
+ il.Emit(method.DeclaringType.IsValueType ? OpCodes.Call : OpCodes.Callvirt, method);
737
+
738
+ if (method.ReturnType == typeof(void))
739
+ {
740
+ il.Emit(OpCodes.Ldnull);
741
+ }
742
+ else if (method.ReturnType.IsValueType)
743
+ {
744
+ il.Emit(OpCodes.Box, method.ReturnType);
745
+ }
746
+
747
+ il.Emit(OpCodes.Ret);
748
+
749
+ return (Func<object, object[], object>)
750
+ dynamicMethod.CreateDelegate(typeof(Func<object, object[], object>));
751
+ #endif
752
+ }
753
+
754
+ public static Func<object[], object> GetStaticMethodInvoker(MethodInfo method)
755
+ {
756
+ if (!method.IsStatic)
757
+ {
758
+ throw new ArgumentException("Method must be static", nameof(method));
759
+ }
760
+
761
+ #if !EMIT_DYNAMIC_IL
762
+ return CreateCompiledStaticMethodInvoker(method);
763
+ #else
764
+ DynamicMethod dynamicMethod = new(
765
+ $"InvokeStatic{method.DeclaringType.Name}_{method.Name}",
766
+ typeof(object),
767
+ new[] { typeof(object[]) },
768
+ method.DeclaringType,
769
+ true
770
+ );
771
+
772
+ ILGenerator il = dynamicMethod.GetILGenerator();
773
+ ParameterInfo[] parameters = method.GetParameters();
774
+
775
+ for (int i = 0; i < parameters.Length; i++)
776
+ {
777
+ il.Emit(OpCodes.Ldarg_0);
778
+ il.Emit(OpCodes.Ldc_I4, i);
779
+ il.Emit(OpCodes.Ldelem_Ref);
780
+
781
+ Type paramType = parameters[i].ParameterType;
782
+ if (paramType.IsValueType)
783
+ {
784
+ il.Emit(OpCodes.Unbox_Any, paramType);
785
+ }
786
+ else
787
+ {
788
+ il.Emit(OpCodes.Castclass, paramType);
789
+ }
790
+ }
791
+
792
+ il.Emit(OpCodes.Call, method);
793
+
794
+ if (method.ReturnType == typeof(void))
795
+ {
796
+ il.Emit(OpCodes.Ldnull);
797
+ }
798
+ else if (method.ReturnType.IsValueType)
799
+ {
800
+ il.Emit(OpCodes.Box, method.ReturnType);
801
+ }
802
+
803
+ il.Emit(OpCodes.Ret);
804
+
805
+ return (Func<object[], object>)
806
+ dynamicMethod.CreateDelegate(typeof(Func<object[], object>));
807
+ #endif
808
+ }
809
+
810
+ public static Func<object[], object> GetConstructor(ConstructorInfo constructor)
811
+ {
812
+ #if !EMIT_DYNAMIC_IL
813
+ return CreateCompiledConstructor(constructor);
814
+ #else
815
+ DynamicMethod dynamicMethod = new(
816
+ $"Create{constructor.DeclaringType.Name}",
817
+ typeof(object),
818
+ new[] { typeof(object[]) },
819
+ constructor.DeclaringType,
820
+ true
821
+ );
822
+
823
+ ILGenerator il = dynamicMethod.GetILGenerator();
824
+ ParameterInfo[] parameters = constructor.GetParameters();
825
+
826
+ for (int i = 0; i < parameters.Length; i++)
827
+ {
828
+ il.Emit(OpCodes.Ldarg_0);
829
+ il.Emit(OpCodes.Ldc_I4, i);
830
+ il.Emit(OpCodes.Ldelem_Ref);
831
+
832
+ Type paramType = parameters[i].ParameterType;
833
+ if (paramType.IsValueType)
834
+ {
835
+ il.Emit(OpCodes.Unbox_Any, paramType);
836
+ }
837
+ else
838
+ {
839
+ il.Emit(OpCodes.Castclass, paramType);
840
+ }
841
+ }
842
+
843
+ il.Emit(OpCodes.Newobj, constructor);
844
+
845
+ if (constructor.DeclaringType.IsValueType)
846
+ {
847
+ il.Emit(OpCodes.Box, constructor.DeclaringType);
848
+ }
849
+
850
+ il.Emit(OpCodes.Ret);
851
+
852
+ return (Func<object[], object>)
853
+ dynamicMethod.CreateDelegate(typeof(Func<object[], object>));
854
+ #endif
855
+ }
856
+
857
+ public static Func<T> GetParameterlessConstructor<T>()
858
+ {
859
+ Type type = typeof(T);
860
+ ConstructorInfo constructor = type.GetConstructor(Type.EmptyTypes);
861
+ if (constructor == null)
862
+ {
863
+ throw new ArgumentException(
864
+ $"Type {type.Name} does not have a parameterless constructor"
865
+ );
866
+ }
867
+
868
+ #if !EMIT_DYNAMIC_IL
869
+ return CreateCompiledParameterlessConstructor<T>(constructor);
870
+ #else
871
+ DynamicMethod dynamicMethod = new(
872
+ $"CreateParameterless{type.Name}",
873
+ typeof(T),
874
+ Type.EmptyTypes,
875
+ type,
876
+ true
877
+ );
878
+
879
+ ILGenerator il = dynamicMethod.GetILGenerator();
880
+ il.Emit(OpCodes.Newobj, constructor);
881
+ il.Emit(OpCodes.Ret);
882
+
883
+ return (Func<T>)dynamicMethod.CreateDelegate(typeof(Func<T>));
884
+ #endif
885
+ }
886
+
887
+ public static Func<T> GetGenericParameterlessConstructor<T>(
888
+ Type genericTypeDefinition,
889
+ params Type[] genericArguments
890
+ )
891
+ {
892
+ Type constructedType = genericTypeDefinition.MakeGenericType(genericArguments);
893
+ ConstructorInfo constructor = constructedType.GetConstructor(Type.EmptyTypes);
894
+ if (constructor == null)
895
+ {
896
+ throw new ArgumentException(
897
+ $"Type {constructedType.Name} does not have a parameterless constructor"
898
+ );
899
+ }
900
+
901
+ #if !EMIT_DYNAMIC_IL
902
+ return CreateCompiledGenericParameterlessConstructor<T>(constructedType, constructor);
903
+ #else
904
+ DynamicMethod dynamicMethod = new(
905
+ $"CreateGenericParameterless{constructedType.Name}",
906
+ typeof(T),
907
+ Type.EmptyTypes,
908
+ constructedType,
909
+ true
910
+ );
911
+
912
+ ILGenerator il = dynamicMethod.GetILGenerator();
913
+ il.Emit(OpCodes.Newobj, constructor);
914
+ if (constructedType.IsValueType && typeof(T) == typeof(object))
915
+ {
916
+ il.Emit(OpCodes.Box, constructedType);
917
+ }
918
+ il.Emit(OpCodes.Ret);
919
+
920
+ return (Func<T>)dynamicMethod.CreateDelegate(typeof(Func<T>));
921
+ #endif
922
+ }
923
+
924
+ public static IEnumerable<Type> GetAllLoadedTypes()
925
+ {
926
+ return GetAllLoadedAssemblies()
927
+ .SelectMany(assembly => GetTypesFromAssembly(assembly))
928
+ .Where(type => type != null);
929
+ }
930
+
931
+ public static IEnumerable<Assembly> GetAllLoadedAssemblies()
932
+ {
933
+ try
934
+ {
935
+ return AppDomain
936
+ .CurrentDomain.GetAssemblies()
937
+ .Where(assembly => assembly != null && !assembly.IsDynamic);
938
+ }
939
+ catch
940
+ {
941
+ return Enumerable.Empty<Assembly>();
942
+ }
943
+ }
944
+
945
+ public static Type[] GetTypesFromAssembly(Assembly assembly)
946
+ {
947
+ if (assembly == null)
948
+ {
949
+ return Type.EmptyTypes;
950
+ }
951
+
952
+ try
953
+ {
954
+ return assembly.GetTypes();
955
+ }
956
+ catch (ReflectionTypeLoadException ex)
957
+ {
958
+ return ex.Types.Where(t => t != null).ToArray();
959
+ }
960
+ catch
961
+ {
962
+ return Type.EmptyTypes;
963
+ }
964
+ }
965
+
966
+ public static Type[] GetTypesFromAssemblyName(string assemblyName)
967
+ {
968
+ try
969
+ {
970
+ Assembly assembly = Assembly.Load(assemblyName);
971
+ return GetTypesFromAssembly(assembly);
972
+ }
973
+ catch
974
+ {
975
+ return Type.EmptyTypes;
976
+ }
977
+ }
978
+
979
+ public static IEnumerable<Type> GetTypesWithAttribute<TAttribute>()
980
+ where TAttribute : Attribute
981
+ {
982
+ return GetAllLoadedTypes().Where(type => HasAttributeSafe<TAttribute>(type));
983
+ }
984
+
985
+ public static IEnumerable<Type> GetTypesWithAttribute(Type attributeType)
986
+ {
987
+ if (attributeType == null || !typeof(Attribute).IsAssignableFrom(attributeType))
988
+ {
989
+ return Enumerable.Empty<Type>();
990
+ }
991
+
992
+ return GetAllLoadedTypes().Where(type => HasAttributeSafe(type, attributeType));
993
+ }
994
+
995
+ public static bool HasAttributeSafe<TAttribute>(
996
+ ICustomAttributeProvider provider,
997
+ bool inherit = true
998
+ )
999
+ where TAttribute : Attribute
1000
+ {
1001
+ if (provider == null)
1002
+ {
1003
+ return false;
1004
+ }
1005
+
1006
+ try
1007
+ {
1008
+ return provider.IsDefined(typeof(TAttribute), inherit);
1009
+ }
1010
+ catch
1011
+ {
1012
+ return false;
1013
+ }
1014
+ }
1015
+
1016
+ public static bool HasAttributeSafe(
1017
+ ICustomAttributeProvider provider,
1018
+ Type attributeType,
1019
+ bool inherit = true
1020
+ )
1021
+ {
1022
+ if (provider == null || attributeType == null)
1023
+ {
1024
+ return false;
1025
+ }
1026
+
1027
+ try
1028
+ {
1029
+ return provider.IsDefined(attributeType, inherit);
1030
+ }
1031
+ catch
1032
+ {
1033
+ return false;
1034
+ }
1035
+ }
1036
+
1037
+ public static TAttribute GetAttributeSafe<TAttribute>(
1038
+ ICustomAttributeProvider provider,
1039
+ bool inherit = true
1040
+ )
1041
+ where TAttribute : Attribute
1042
+ {
1043
+ if (provider == null)
1044
+ {
1045
+ return default;
1046
+ }
1047
+
1048
+ try
1049
+ {
1050
+ if (provider.IsDefined(typeof(TAttribute), inherit))
1051
+ {
1052
+ object[] attributes = provider.GetCustomAttributes(typeof(TAttribute), inherit);
1053
+ return attributes.Length > 0 ? attributes[0] as TAttribute : default;
1054
+ }
1055
+ }
1056
+ catch
1057
+ {
1058
+ // Swallow
1059
+ }
1060
+
1061
+ return default;
1062
+ }
1063
+
1064
+ public static Attribute GetAttributeSafe(
1065
+ ICustomAttributeProvider provider,
1066
+ Type attributeType,
1067
+ bool inherit = true
1068
+ )
1069
+ {
1070
+ if (provider == null || attributeType == null)
1071
+ {
1072
+ return null;
1073
+ }
1074
+
1075
+ try
1076
+ {
1077
+ if (provider.IsDefined(attributeType, inherit))
1078
+ {
1079
+ object[] attributes = provider.GetCustomAttributes(attributeType, inherit);
1080
+ return attributes.Length > 0 ? attributes[0] as Attribute : null;
1081
+ }
1082
+ }
1083
+ catch
1084
+ {
1085
+ // Swallow
1086
+ }
1087
+
1088
+ return null;
1089
+ }
1090
+
1091
+ public static TAttribute[] GetAllAttributesSafe<TAttribute>(
1092
+ ICustomAttributeProvider provider,
1093
+ bool inherit = true
1094
+ )
1095
+ where TAttribute : Attribute
1096
+ {
1097
+ if (provider == null)
1098
+ {
1099
+ return Array.Empty<TAttribute>();
1100
+ }
1101
+
1102
+ try
1103
+ {
1104
+ if (provider.IsDefined(typeof(TAttribute), inherit))
1105
+ {
1106
+ return provider
1107
+ .GetCustomAttributes(typeof(TAttribute), inherit)
1108
+ .OfType<TAttribute>()
1109
+ .ToArray();
1110
+ }
1111
+ return Array.Empty<TAttribute>();
1112
+ }
1113
+ catch
1114
+ {
1115
+ return Array.Empty<TAttribute>();
1116
+ }
1117
+ }
1118
+
1119
+ public static Attribute[] GetAllAttributesSafe(
1120
+ ICustomAttributeProvider provider,
1121
+ bool inherit = true
1122
+ )
1123
+ {
1124
+ if (provider == null)
1125
+ {
1126
+ return Array.Empty<Attribute>();
1127
+ }
1128
+
1129
+ try
1130
+ {
1131
+ return provider.GetCustomAttributes(inherit).OfType<Attribute>().ToArray();
1132
+ }
1133
+ catch
1134
+ {
1135
+ return Array.Empty<Attribute>();
1136
+ }
1137
+ }
1138
+
1139
+ public static Attribute[] GetAllAttributesSafe(
1140
+ ICustomAttributeProvider provider,
1141
+ Type attributeType,
1142
+ bool inherit = true
1143
+ )
1144
+ {
1145
+ if (provider == null || attributeType == null)
1146
+ {
1147
+ return Array.Empty<Attribute>();
1148
+ }
1149
+
1150
+ try
1151
+ {
1152
+ if (provider.IsDefined(attributeType, inherit))
1153
+ {
1154
+ return provider
1155
+ .GetCustomAttributes(attributeType, inherit)
1156
+ .OfType<Attribute>()
1157
+ .ToArray();
1158
+ }
1159
+ return Array.Empty<Attribute>();
1160
+ }
1161
+ catch
1162
+ {
1163
+ return Array.Empty<Attribute>();
1164
+ }
1165
+ }
1166
+
1167
+ public static Dictionary<string, object> GetAllAttributeValuesSafe(
1168
+ ICustomAttributeProvider provider,
1169
+ bool inherit = true
1170
+ )
1171
+ {
1172
+ Dictionary<string, object> result = new();
1173
+
1174
+ foreach (Attribute attr in GetAllAttributesSafe(provider, inherit))
1175
+ {
1176
+ try
1177
+ {
1178
+ Type attrType = attr.GetType();
1179
+ string key = attrType.Name;
1180
+
1181
+ if (key.EndsWith("Attribute"))
1182
+ {
1183
+ key = key.Substring(0, key.Length - 9);
1184
+ }
1185
+
1186
+ result.TryAdd(key, attr);
1187
+ }
1188
+ catch
1189
+ {
1190
+ // Skip this attribute if we can't process it
1191
+ }
1192
+ }
1193
+
1194
+ return result;
1195
+ }
1196
+
1197
+ public static MethodInfo[] GetMethodsWithAttributeSafe<TAttribute>(
1198
+ Type type,
1199
+ bool inherit = true
1200
+ )
1201
+ where TAttribute : Attribute
1202
+ {
1203
+ if (type == null)
1204
+ {
1205
+ return Array.Empty<MethodInfo>();
1206
+ }
1207
+
1208
+ try
1209
+ {
1210
+ bool localInherit = inherit;
1211
+ return type.GetMethods(
1212
+ BindingFlags.Public
1213
+ | BindingFlags.NonPublic
1214
+ | BindingFlags.Instance
1215
+ | BindingFlags.Static
1216
+ )
1217
+ .Where(method => HasAttributeSafe<TAttribute>(method, localInherit))
1218
+ .ToArray();
1219
+ }
1220
+ catch
1221
+ {
1222
+ return Array.Empty<MethodInfo>();
1223
+ }
1224
+ }
1225
+
1226
+ public static PropertyInfo[] GetPropertiesWithAttributeSafe<TAttribute>(
1227
+ Type type,
1228
+ bool inherit = true
1229
+ )
1230
+ where TAttribute : Attribute
1231
+ {
1232
+ if (type == null)
1233
+ {
1234
+ return Array.Empty<PropertyInfo>();
1235
+ }
1236
+
1237
+ try
1238
+ {
1239
+ bool localInherit = inherit;
1240
+ return type.GetProperties(
1241
+ BindingFlags.Public
1242
+ | BindingFlags.NonPublic
1243
+ | BindingFlags.Instance
1244
+ | BindingFlags.Static
1245
+ )
1246
+ .Where(property => HasAttributeSafe<TAttribute>(property, localInherit))
1247
+ .ToArray();
1248
+ }
1249
+ catch
1250
+ {
1251
+ return Array.Empty<PropertyInfo>();
1252
+ }
1253
+ }
1254
+
1255
+ public static FieldInfo[] GetFieldsWithAttributeSafe<TAttribute>(
1256
+ Type type,
1257
+ bool inherit = true
1258
+ )
1259
+ where TAttribute : Attribute
1260
+ {
1261
+ if (type == null)
1262
+ {
1263
+ return Array.Empty<FieldInfo>();
1264
+ }
1265
+
1266
+ try
1267
+ {
1268
+ bool localInherit = inherit;
1269
+ return type.GetFields(
1270
+ BindingFlags.Public
1271
+ | BindingFlags.NonPublic
1272
+ | BindingFlags.Instance
1273
+ | BindingFlags.Static
1274
+ )
1275
+ .Where(field => HasAttributeSafe<TAttribute>(field, localInherit))
1276
+ .ToArray();
1277
+ }
1278
+ catch
1279
+ {
1280
+ return Array.Empty<FieldInfo>();
1281
+ }
1282
+ }
1283
+
1284
+ private static bool CheckExpressionCompilationSupport()
1285
+ {
1286
+ #if !SUPPORT_EXPRESSION_COMPILE
1287
+ return false;
1288
+ #else
1289
+ try
1290
+ {
1291
+ // Test if expression compilation works by trying a simple lambda
1292
+ Expression<Func<int>> testExpr = () => 42;
1293
+ Func<int> compiled = testExpr.Compile();
1294
+ return compiled() == 42;
1295
+ }
1296
+ catch
1297
+ {
1298
+ return false;
1299
+ }
1300
+ #endif
1301
+ }
1302
+
1303
+ private static Func<object, object[], object> CreateCompiledMethodInvoker(MethodInfo method)
1304
+ {
1305
+ if (!CanCompileExpressions)
1306
+ {
1307
+ return CreateDelegateMethodInvoker(method)
1308
+ ?? ((instance, args) => method.Invoke(instance, args));
1309
+ }
1310
+
1311
+ try
1312
+ {
1313
+ ParameterExpression instanceParam = Expression.Parameter(
1314
+ typeof(object),
1315
+ "instance"
1316
+ );
1317
+ ParameterExpression argsParam = Expression.Parameter(typeof(object[]), "args");
1318
+
1319
+ Expression instanceExpression = method.DeclaringType.IsValueType
1320
+ ? Expression.Unbox(instanceParam, method.DeclaringType)
1321
+ : Expression.Convert(instanceParam, method.DeclaringType);
1322
+
1323
+ ParameterInfo[] parameters = method.GetParameters();
1324
+ Expression[] paramExpressions = new Expression[parameters.Length];
1325
+
1326
+ for (int i = 0; i < parameters.Length; i++)
1327
+ {
1328
+ Expression argExpression = Expression.ArrayIndex(
1329
+ argsParam,
1330
+ Expression.Constant(i)
1331
+ );
1332
+ Type paramType = parameters[i].ParameterType;
1333
+ paramExpressions[i] = paramType.IsValueType
1334
+ ? Expression.Unbox(argExpression, paramType)
1335
+ : Expression.Convert(argExpression, paramType);
1336
+ }
1337
+
1338
+ Expression callExpression = Expression.Call(
1339
+ instanceExpression,
1340
+ method,
1341
+ paramExpressions
1342
+ );
1343
+
1344
+ Expression returnExpression =
1345
+ method.ReturnType == typeof(void)
1346
+ ? Expression.Block(callExpression, Expression.Constant(null))
1347
+ : method.ReturnType.IsValueType
1348
+ ? Expression.Convert(callExpression, typeof(object))
1349
+ : callExpression;
1350
+
1351
+ return Expression
1352
+ .Lambda<Func<object, object[], object>>(
1353
+ returnExpression,
1354
+ instanceParam,
1355
+ argsParam
1356
+ )
1357
+ .Compile();
1358
+ }
1359
+ catch
1360
+ {
1361
+ return (instance, args) => method.Invoke(instance, args);
1362
+ }
1363
+ }
1364
+
1365
+ private static Func<object[], object> CreateCompiledStaticMethodInvoker(MethodInfo method)
1366
+ {
1367
+ if (!CanCompileExpressions)
1368
+ {
1369
+ return CreateDelegateStaticMethodInvoker(method)
1370
+ ?? (args => method.Invoke(null, args));
1371
+ }
1372
+
1373
+ try
1374
+ {
1375
+ ParameterExpression argsParam = Expression.Parameter(typeof(object[]), "args");
1376
+
1377
+ ParameterInfo[] parameters = method.GetParameters();
1378
+ Expression[] paramExpressions = new Expression[parameters.Length];
1379
+
1380
+ for (int i = 0; i < parameters.Length; i++)
1381
+ {
1382
+ Expression argExpression = Expression.ArrayIndex(
1383
+ argsParam,
1384
+ Expression.Constant(i)
1385
+ );
1386
+ Type paramType = parameters[i].ParameterType;
1387
+ paramExpressions[i] = paramType.IsValueType
1388
+ ? Expression.Unbox(argExpression, paramType)
1389
+ : Expression.Convert(argExpression, paramType);
1390
+ }
1391
+
1392
+ Expression callExpression = Expression.Call(method, paramExpressions);
1393
+
1394
+ Expression returnExpression =
1395
+ method.ReturnType == typeof(void)
1396
+ ? Expression.Block(callExpression, Expression.Constant(null))
1397
+ : method.ReturnType.IsValueType
1398
+ ? Expression.Convert(callExpression, typeof(object))
1399
+ : callExpression;
1400
+
1401
+ return Expression
1402
+ .Lambda<Func<object[], object>>(returnExpression, argsParam)
1403
+ .Compile();
1404
+ }
1405
+ catch
1406
+ {
1407
+ return args => method.Invoke(null, args);
1408
+ }
1409
+ }
1410
+
1411
+ private static Func<object[], object> CreateCompiledConstructor(ConstructorInfo constructor)
1412
+ {
1413
+ if (!CanCompileExpressions)
1414
+ {
1415
+ return CreateDelegateConstructor(constructor) ?? (args => constructor.Invoke(args));
1416
+ }
1417
+
1418
+ try
1419
+ {
1420
+ ParameterExpression argsParam = Expression.Parameter(typeof(object[]), "args");
1421
+
1422
+ ParameterInfo[] parameters = constructor.GetParameters();
1423
+ Expression[] paramExpressions = new Expression[parameters.Length];
1424
+
1425
+ for (int i = 0; i < parameters.Length; i++)
1426
+ {
1427
+ Expression argExpression = Expression.ArrayIndex(
1428
+ argsParam,
1429
+ Expression.Constant(i)
1430
+ );
1431
+ Type paramType = parameters[i].ParameterType;
1432
+ paramExpressions[i] = paramType.IsValueType
1433
+ ? Expression.Unbox(argExpression, paramType)
1434
+ : Expression.Convert(argExpression, paramType);
1435
+ }
1436
+
1437
+ Expression newExpression = Expression.New(constructor, paramExpressions);
1438
+
1439
+ Expression returnExpression = constructor.DeclaringType.IsValueType
1440
+ ? Expression.Convert(newExpression, typeof(object))
1441
+ : newExpression;
1442
+
1443
+ return Expression
1444
+ .Lambda<Func<object[], object>>(returnExpression, argsParam)
1445
+ .Compile();
1446
+ }
1447
+ catch
1448
+ {
1449
+ return args => constructor.Invoke(args);
1450
+ }
1451
+ }
1452
+
1453
+ private static Func<T> CreateCompiledParameterlessConstructor<T>(
1454
+ ConstructorInfo constructor
1455
+ )
1456
+ {
1457
+ if (!CanCompileExpressions)
1458
+ {
1459
+ return CreateDelegateParameterlessConstructor<T>(constructor)
1460
+ ?? (() => (T)Activator.CreateInstance(typeof(T)));
1461
+ }
1462
+
1463
+ try
1464
+ {
1465
+ Expression newExpression = Expression.New(constructor);
1466
+ return Expression.Lambda<Func<T>>(newExpression).Compile();
1467
+ }
1468
+ catch
1469
+ {
1470
+ return () => (T)Activator.CreateInstance(typeof(T));
1471
+ }
1472
+ }
1473
+
1474
+ private static Func<T> CreateCompiledGenericParameterlessConstructor<T>(
1475
+ Type constructedType,
1476
+ ConstructorInfo constructor
1477
+ )
1478
+ {
1479
+ if (!CanCompileExpressions)
1480
+ {
1481
+ return () => (T)Activator.CreateInstance(constructedType);
1482
+ }
1483
+
1484
+ try
1485
+ {
1486
+ Expression newExpression = Expression.New(constructor);
1487
+ Expression convertExpression =
1488
+ constructedType.IsValueType && typeof(T) == typeof(object)
1489
+ ? Expression.Convert(newExpression, typeof(object))
1490
+ : newExpression;
1491
+
1492
+ return Expression.Lambda<Func<T>>(convertExpression).Compile();
1493
+ }
1494
+ catch
1495
+ {
1496
+ return () => (T)Activator.CreateInstance(constructedType);
1497
+ }
1498
+ }
1499
+
1500
+ private static Func<object, object> CreateCompiledFieldGetter(FieldInfo field)
1501
+ {
1502
+ if (!CanCompileExpressions)
1503
+ {
1504
+ return CreateDelegateFieldGetter(field) ?? field.GetValue;
1505
+ }
1506
+
1507
+ try
1508
+ {
1509
+ ParameterExpression instanceParam = Expression.Parameter(
1510
+ typeof(object),
1511
+ "instance"
1512
+ );
1513
+
1514
+ Expression instanceExpression = field.DeclaringType.IsValueType
1515
+ ? Expression.Unbox(instanceParam, field.DeclaringType)
1516
+ : Expression.Convert(instanceParam, field.DeclaringType);
1517
+
1518
+ Expression fieldExpression = Expression.Field(instanceExpression, field);
1519
+
1520
+ Expression returnExpression = field.FieldType.IsValueType
1521
+ ? Expression.Convert(fieldExpression, typeof(object))
1522
+ : fieldExpression;
1523
+
1524
+ return Expression
1525
+ .Lambda<Func<object, object>>(returnExpression, instanceParam)
1526
+ .Compile();
1527
+ }
1528
+ catch
1529
+ {
1530
+ return field.GetValue;
1531
+ }
1532
+ }
1533
+
1534
+ private static Func<object, object> CreateCompiledPropertyGetter(PropertyInfo property)
1535
+ {
1536
+ if (!CanCompileExpressions)
1537
+ {
1538
+ return CreateDelegatePropertyGetter(property) ?? property.GetValue;
1539
+ }
1540
+
1541
+ try
1542
+ {
1543
+ MethodInfo getMethod = property.GetGetMethod(true);
1544
+ if (getMethod == null)
1545
+ {
1546
+ return property.GetValue;
1547
+ }
1548
+
1549
+ ParameterExpression instanceParam = Expression.Parameter(
1550
+ typeof(object),
1551
+ "instance"
1552
+ );
1553
+
1554
+ Expression instanceExpression = property.DeclaringType.IsValueType
1555
+ ? Expression.Unbox(instanceParam, property.DeclaringType)
1556
+ : Expression.Convert(instanceParam, property.DeclaringType);
1557
+
1558
+ Expression propertyExpression = Expression.Property(instanceExpression, property);
1559
+
1560
+ Expression returnExpression = property.PropertyType.IsValueType
1561
+ ? Expression.Convert(propertyExpression, typeof(object))
1562
+ : propertyExpression;
1563
+
1564
+ return Expression
1565
+ .Lambda<Func<object, object>>(returnExpression, instanceParam)
1566
+ .Compile();
1567
+ }
1568
+ catch
1569
+ {
1570
+ return property.GetValue;
1571
+ }
1572
+ }
1573
+
1574
+ private static Func<object> CreateCompiledStaticFieldGetter(FieldInfo field)
1575
+ {
1576
+ if (!CanCompileExpressions)
1577
+ {
1578
+ return () => field.GetValue(null);
1579
+ }
1580
+
1581
+ try
1582
+ {
1583
+ Expression fieldExpression = Expression.Field(null, field);
1584
+
1585
+ Expression returnExpression = field.FieldType.IsValueType
1586
+ ? Expression.Convert(fieldExpression, typeof(object))
1587
+ : fieldExpression;
1588
+
1589
+ return Expression.Lambda<Func<object>>(returnExpression).Compile();
1590
+ }
1591
+ catch
1592
+ {
1593
+ return () => field.GetValue(null);
1594
+ }
1595
+ }
1596
+
1597
+ private static Action<object, object> CreateCompiledFieldSetter(FieldInfo field)
1598
+ {
1599
+ if (!CanCompileExpressions)
1600
+ {
1601
+ return field.SetValue;
1602
+ }
1603
+
1604
+ try
1605
+ {
1606
+ ParameterExpression instanceParam = Expression.Parameter(
1607
+ typeof(object),
1608
+ "instance"
1609
+ );
1610
+ ParameterExpression valueParam = Expression.Parameter(typeof(object), "value");
1611
+
1612
+ Expression instanceExpression = field.DeclaringType.IsValueType
1613
+ ? Expression.Unbox(instanceParam, field.DeclaringType)
1614
+ : Expression.Convert(instanceParam, field.DeclaringType);
1615
+
1616
+ Expression valueExpression = field.FieldType.IsValueType
1617
+ ? Expression.Unbox(valueParam, field.FieldType)
1618
+ : Expression.Convert(valueParam, field.FieldType);
1619
+
1620
+ Expression assignExpression = Expression.Assign(
1621
+ Expression.Field(instanceExpression, field),
1622
+ valueExpression
1623
+ );
1624
+
1625
+ return Expression
1626
+ .Lambda<Action<object, object>>(assignExpression, instanceParam, valueParam)
1627
+ .Compile();
1628
+ }
1629
+ catch
1630
+ {
1631
+ return field.SetValue;
1632
+ }
1633
+ }
1634
+
1635
+ private static Action<object> CreateCompiledStaticFieldSetter(FieldInfo field)
1636
+ {
1637
+ if (!CanCompileExpressions)
1638
+ {
1639
+ return value => field.SetValue(null, value);
1640
+ }
1641
+
1642
+ try
1643
+ {
1644
+ ParameterExpression valueParam = Expression.Parameter(typeof(object), "value");
1645
+
1646
+ Expression valueExpression = field.FieldType.IsValueType
1647
+ ? Expression.Unbox(valueParam, field.FieldType)
1648
+ : Expression.Convert(valueParam, field.FieldType);
1649
+
1650
+ Expression assignExpression = Expression.Assign(
1651
+ Expression.Field(null, field),
1652
+ valueExpression
1653
+ );
1654
+
1655
+ return Expression.Lambda<Action<object>>(assignExpression, valueParam).Compile();
1656
+ }
1657
+ catch
1658
+ {
1659
+ return value => field.SetValue(null, value);
1660
+ }
1661
+ }
1662
+
1663
+ private static Func<object, object[], object> CreateDelegateMethodInvoker(MethodInfo method)
1664
+ {
1665
+ try
1666
+ {
1667
+ // For IL2CPP/WebGL, focus on simple optimizations that avoid DynamicInvoke
1668
+ // which can be slower than direct reflection in some cases
1669
+
1670
+ ParameterInfo[] parameters = method.GetParameters();
1671
+
1672
+ // Only optimize very simple cases to avoid DynamicInvoke overhead
1673
+ if (parameters.Length == 0 && method.IsStatic)
1674
+ {
1675
+ if (method.ReturnType == typeof(void))
1676
+ {
1677
+ Action staticAction = (Action)
1678
+ Delegate.CreateDelegate(typeof(Action), method);
1679
+ return (instance, args) =>
1680
+ {
1681
+ staticAction();
1682
+ return null;
1683
+ };
1684
+ }
1685
+
1686
+ if (method.ReturnType == typeof(int))
1687
+ {
1688
+ Func<int> staticFunc =
1689
+ (Func<int>)Delegate.CreateDelegate(typeof(Func<int>), method);
1690
+ return (instance, args) => staticFunc();
1691
+ }
1692
+
1693
+ if (method.ReturnType == typeof(string))
1694
+ {
1695
+ Func<string> staticFunc =
1696
+ (Func<string>)Delegate.CreateDelegate(typeof(Func<string>), method);
1697
+ return (instance, args) => staticFunc();
1698
+ }
1699
+
1700
+ if (method.ReturnType == typeof(bool))
1701
+ {
1702
+ Func<bool> staticFunc =
1703
+ (Func<bool>)Delegate.CreateDelegate(typeof(Func<bool>), method);
1704
+ return (instance, args) => staticFunc();
1705
+ }
1706
+ }
1707
+
1708
+ // For most other cases, direct reflection is often faster than DynamicInvoke
1709
+ return null;
1710
+ }
1711
+ catch
1712
+ {
1713
+ return null; // Fallback to reflection
1714
+ }
1715
+ }
1716
+
1717
+ private static Func<object[], object> CreateDelegateStaticMethodInvoker(MethodInfo method)
1718
+ {
1719
+ try
1720
+ {
1721
+ ParameterInfo[] parameters = method.GetParameters();
1722
+
1723
+ // Only optimize simple static methods with no parameters to avoid DynamicInvoke
1724
+ if (parameters.Length == 0)
1725
+ {
1726
+ if (method.ReturnType == typeof(void))
1727
+ {
1728
+ Action action = (Action)Delegate.CreateDelegate(typeof(Action), method);
1729
+ return args =>
1730
+ {
1731
+ action();
1732
+ return null;
1733
+ };
1734
+ }
1735
+
1736
+ if (method.ReturnType == typeof(int))
1737
+ {
1738
+ Func<int> func =
1739
+ (Func<int>)Delegate.CreateDelegate(typeof(Func<int>), method);
1740
+ return args => func();
1741
+ }
1742
+
1743
+ if (method.ReturnType == typeof(string))
1744
+ {
1745
+ Func<string> func =
1746
+ (Func<string>)Delegate.CreateDelegate(typeof(Func<string>), method);
1747
+ return args => func();
1748
+ }
1749
+
1750
+ if (method.ReturnType == typeof(bool))
1751
+ {
1752
+ Func<bool> func =
1753
+ (Func<bool>)Delegate.CreateDelegate(typeof(Func<bool>), method);
1754
+ return args => func();
1755
+ }
1756
+ }
1757
+
1758
+ // For other cases, reflection is often faster than DynamicInvoke
1759
+ return null;
1760
+ }
1761
+ catch
1762
+ {
1763
+ return null;
1764
+ }
1765
+ }
1766
+
1767
+ private static Func<object[], object> CreateDelegateConstructor(ConstructorInfo constructor)
1768
+ {
1769
+ try
1770
+ {
1771
+ ParameterInfo[] parameters = constructor.GetParameters();
1772
+ Type declaringType = constructor.DeclaringType;
1773
+
1774
+ // For constructors, we can use Activator.CreateInstance with optimizations
1775
+ // or create wrapper delegates that call the constructor
1776
+
1777
+ if (parameters.Length == 0)
1778
+ {
1779
+ // Use cached Activator.CreateInstance for parameterless constructors
1780
+ return args => Activator.CreateInstance(declaringType);
1781
+ }
1782
+
1783
+ if (parameters.Length == 1)
1784
+ {
1785
+ Type paramType = parameters[0].ParameterType;
1786
+ return args => Activator.CreateInstance(declaringType, args[0]);
1787
+ }
1788
+
1789
+ if (parameters.Length == 2)
1790
+ {
1791
+ return args => Activator.CreateInstance(declaringType, args[0], args[1]);
1792
+ }
1793
+
1794
+ if (parameters.Length <= 4)
1795
+ {
1796
+ // For up to 4 parameters, use Activator.CreateInstance which is reasonably fast
1797
+ return args => Activator.CreateInstance(declaringType, args);
1798
+ }
1799
+
1800
+ // For more complex constructors, fallback to reflection
1801
+ return null;
1802
+ }
1803
+ catch
1804
+ {
1805
+ return null;
1806
+ }
1807
+ }
1808
+
1809
+ private static Func<T> CreateDelegateParameterlessConstructor<T>(
1810
+ ConstructorInfo constructor
1811
+ )
1812
+ {
1813
+ try
1814
+ {
1815
+ // For parameterless constructors, we can use optimized Activator.CreateInstance
1816
+ if (constructor.GetParameters().Length == 0)
1817
+ {
1818
+ return () => (T)Activator.CreateInstance(typeof(T));
1819
+ }
1820
+
1821
+ return null;
1822
+ }
1823
+ catch
1824
+ {
1825
+ return null;
1826
+ }
1827
+ }
1828
+
1829
+ private static Func<object, object> CreateDelegateFieldGetter(FieldInfo field)
1830
+ {
1831
+ try
1832
+ {
1833
+ if (field.IsStatic)
1834
+ {
1835
+ // For static fields, create a simple wrapper
1836
+ return instance => field.GetValue(null);
1837
+ }
1838
+
1839
+ // For instance fields, we can't easily create delegates, so use optimized wrapper
1840
+ return instance => field.GetValue(instance);
1841
+ }
1842
+ catch
1843
+ {
1844
+ return null;
1845
+ }
1846
+ }
1847
+
1848
+ private static Func<object, object> CreateDelegatePropertyGetter(PropertyInfo property)
1849
+ {
1850
+ try
1851
+ {
1852
+ MethodInfo getMethod = property.GetGetMethod(true);
1853
+ if (getMethod == null)
1854
+ {
1855
+ return null;
1856
+ }
1857
+
1858
+ if (getMethod.IsStatic)
1859
+ {
1860
+ Type funcType = typeof(Func<>).MakeGenericType(property.PropertyType);
1861
+ Delegate getter = Delegate.CreateDelegate(funcType, getMethod);
1862
+ return instance => getter.DynamicInvoke();
1863
+ }
1864
+ else
1865
+ {
1866
+ Type funcType = typeof(Func<,>).MakeGenericType(
1867
+ property.DeclaringType,
1868
+ property.PropertyType
1869
+ );
1870
+ Delegate getter = Delegate.CreateDelegate(funcType, getMethod);
1871
+ return instance => getter.DynamicInvoke(instance);
1872
+ }
1873
+ }
1874
+ catch
1875
+ {
1876
+ return null;
1877
+ }
1878
+ }
1879
+
1880
+ private static Func<object, object> CreateGenericFieldGetter(FieldInfo field)
1881
+ {
1882
+ try
1883
+ {
1884
+ // For now, just use direct field access - it's already reasonably fast
1885
+ if (field.IsStatic)
1886
+ {
1887
+ return instance => field.GetValue(null);
1888
+ }
1889
+
1890
+ return instance => field.GetValue(instance);
1891
+ }
1892
+ catch
1893
+ {
1894
+ return null;
1895
+ }
1896
+ }
1897
+
1898
+ private static Type GetActionType(Type[] parameterTypes)
1899
+ {
1900
+ switch (parameterTypes.Length)
1901
+ {
1902
+ case 0:
1903
+ return typeof(Action);
1904
+ case 1:
1905
+ return typeof(Action<>).MakeGenericType(parameterTypes);
1906
+ case 2:
1907
+ return typeof(Action<,>).MakeGenericType(parameterTypes);
1908
+ case 3:
1909
+ return typeof(Action<,,>).MakeGenericType(parameterTypes);
1910
+ case 4:
1911
+ return typeof(Action<,,,>).MakeGenericType(parameterTypes);
1912
+ default:
1913
+ return null;
1914
+ }
1915
+ }
1916
+
1917
+ private static Type GetFuncType(Type[] typeArgs)
1918
+ {
1919
+ switch (typeArgs.Length)
1920
+ {
1921
+ case 1:
1922
+ return typeof(Func<>).MakeGenericType(typeArgs);
1923
+ case 2:
1924
+ return typeof(Func<,>).MakeGenericType(typeArgs);
1925
+ case 3:
1926
+ return typeof(Func<,,>).MakeGenericType(typeArgs);
1927
+ case 4:
1928
+ return typeof(Func<,,,>).MakeGenericType(typeArgs);
1929
+ case 5:
1930
+ return typeof(Func<,,,,>).MakeGenericType(typeArgs);
1931
+ default:
1932
+ return null;
1933
+ }
1934
+ }
589
1935
  }
590
1936
  }