------ #### MyDbV4 V3.0.2107.2901 - *.[新增]新增支持计算文件MD5。 - *.[新增]部分DataProvider功能移植到DbExtension里,增加扩展性。 - *.[新增]UnixTimeToDateTime和JSTimeToDateTime新增支持long参数。 - *.[合并]合并RyWeb项目到MyDb里。 #### ryControlsV4 V3.0.2107.2901 - *.[改进]优化减少大量IDE警告和消息。
115 lines
3.9 KiB
C#
115 lines
3.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Reflection;
|
|
using System.Linq.Expressions;
|
|
|
|
namespace Sheng.Winform.Controls.Kernal
|
|
{
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public interface IMethodInvoker
|
|
{
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="instance"></param>
|
|
/// <param name="parameters"></param>
|
|
/// <returns></returns>
|
|
object Invoke(object instance, params object[] parameters);
|
|
}
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public class MethodInvoker : IMethodInvoker
|
|
{
|
|
private readonly Func<object, object[], object> m_invoker;
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public MethodInfo MethodInfo { get; private set; }
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="methodInfo"></param>
|
|
public MethodInvoker(MethodInfo methodInfo)
|
|
{
|
|
this.MethodInfo = methodInfo;
|
|
this.m_invoker = CreateInvokeDelegate(methodInfo);
|
|
}
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="instance"></param>
|
|
/// <param name="parameters"></param>
|
|
/// <returns></returns>
|
|
public object Invoke(object instance, params object[] parameters)
|
|
{
|
|
return this.m_invoker(instance, parameters);
|
|
}
|
|
|
|
private static Func<object, object[], object> CreateInvokeDelegate(MethodInfo methodInfo)
|
|
{
|
|
// Target: ((TInstance)instance).Method((T0)parameters[0], (T1)parameters[1], ...)
|
|
|
|
// parameters to execute
|
|
var instanceParameter = Expression.Parameter(typeof(object), "instance");
|
|
var parametersParameter = Expression.Parameter(typeof(object[]), "parameters");
|
|
|
|
// build parameter list
|
|
var parameterExpressions = new List<Expression>();
|
|
var paramInfos = methodInfo.GetParameters();
|
|
for (int i = 0; i < paramInfos.Length; i++)
|
|
{
|
|
// (Ti)parameters[i]
|
|
BinaryExpression valueObj = Expression.ArrayIndex(
|
|
parametersParameter, Expression.Constant(i));
|
|
UnaryExpression valueCast = Expression.Convert(
|
|
valueObj, paramInfos[i].ParameterType);
|
|
|
|
parameterExpressions.Add(valueCast);
|
|
}
|
|
|
|
// non-instance for static method, or ((TInstance)instance)
|
|
var instanceCast = methodInfo.IsStatic ? null :
|
|
Expression.Convert(instanceParameter, methodInfo.ReflectedType);
|
|
|
|
// static invoke or ((TInstance)instance).Method
|
|
var methodCall = Expression.Call(instanceCast, methodInfo, parameterExpressions);
|
|
|
|
// ((TInstance)instance).Method((T0)parameters[0], (T1)parameters[1], ...)
|
|
if (methodCall.Type == typeof(void))
|
|
{
|
|
var lambda = Expression.Lambda<Action<object, object[]>>(
|
|
methodCall, instanceParameter, parametersParameter);
|
|
|
|
Action<object, object[]> execute = lambda.Compile();
|
|
return (instance, parameters) =>
|
|
{
|
|
execute(instance, parameters);
|
|
return null;
|
|
};
|
|
}
|
|
else
|
|
{
|
|
var castMethodCall = Expression.Convert(methodCall, typeof(object));
|
|
var lambda =Expression.Lambda<Func<object, object[], object>>(
|
|
castMethodCall, instanceParameter, parametersParameter);
|
|
|
|
return lambda.Compile();
|
|
}
|
|
}
|
|
|
|
#region IMethodInvoker Members
|
|
|
|
object IMethodInvoker.Invoke(object instance, params object[] parameters)
|
|
{
|
|
return this.Invoke(instance, parameters);
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|