@@ -17,6 +17,7 @@ public class TaskUtils
1717 private static readonly ConcurrentDictionary < Type , Func < object , object > > _asValueTaskFuncCache = new ConcurrentDictionary < Type , Func < object , object > > ( ) ;
1818 private static readonly ConcurrentDictionary < Type , Func < object , object > > _resultFuncCache = new ConcurrentDictionary < Type , Func < object , object > > ( ) ;
1919 private static readonly ConcurrentDictionary < TypeInfo , Func < object , Task > > _valueTaskAsTaskFuncCache = new ConcurrentDictionary < TypeInfo , Func < object , Task > > ( ) ;
20+ private static readonly ConcurrentDictionary < MethodInfo , Func < object , object ? [ ] ? , object ? > > _methodFuncCache = new ConcurrentDictionary < MethodInfo , Func < object , object ? [ ] ? , object ? > > ( ) ;
2021
2122 public static Func < object , object > TaskResultFunc ( Type returnType )
2223 {
@@ -74,6 +75,45 @@ public static Task ValueTaskWithResultToTask(object value, TypeInfo valueTypeInf
7475 return func ( value ) ;
7576 }
7677
78+ public static Func < object , object ? [ ] ? , object ? > InvokeMethod ( MethodInfo methodInfo )
79+ {
80+ var methodFunc = _methodFuncCache . GetOrAdd ( methodInfo , method =>
81+ {
82+ var targetParameter = Expression . Parameter ( typeof ( object ) , "target" ) ;
83+ var parametersParameter = Expression . Parameter ( typeof ( object ? [ ] ) , "parameters" ) ;
84+
85+ var paramInfos = method . GetParameters ( ) ;
86+ var parameters = new List < Expression > ( paramInfos . Length ) ;
87+ for ( int i = 0 ; i < paramInfos . Length ; i ++ )
88+ {
89+ var valueObj = Expression . ArrayIndex ( parametersParameter , Expression . Constant ( i ) ) ;
90+ var valueCast = Expression . Convert ( valueObj , paramInfos [ i ] . ParameterType ) ;
91+
92+ parameters . Add ( valueCast ) ;
93+ }
94+
95+ Type targetType = method . DeclaringType ;
96+ var instanceCast = Expression . Convert ( targetParameter , targetType ) ;
97+ var methodCall = Expression . Call ( instanceCast , method , parameters ) ;
98+
99+ if ( methodCall . Type == typeof ( void ) )
100+ {
101+ var lambdaAction = Expression . Lambda < Action < object , object ? [ ] ? > > ( methodCall , targetParameter , parametersParameter ) ;
102+ return ( target , parameters ) =>
103+ {
104+ lambdaAction . Compile ( ) . Invoke ( target , parameters ) ;
105+ return null ;
106+ } ;
107+ }
108+
109+ var castMethodCall = Expression . Convert ( methodCall , typeof ( object ) ) ;
110+ var lambdaFunc = Expression . Lambda < Func < object , object ? [ ] ? , object ? > > ( castMethodCall , targetParameter , parametersParameter ) ;
111+ return lambdaFunc . Compile ( ) ;
112+ } ) ;
113+
114+ return methodFunc ;
115+ }
116+
77117 public static bool IsAsyncMethod ( MethodInfo method )
78118 {
79119 bool isDefAsync = Attribute . IsDefined ( method , typeof ( AsyncStateMachineAttribute ) , false ) ;
0 commit comments