• 使用Expressions调用实体的方法


      Expressions如何实现反射调用实现方法类似的功能呢(并且效率比使用反射高)?下面就把方法分享给大家:

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Linq.Expressions;
     5 using System.Reflection;
     6 using System.Text;
     7 using System.Threading.Tasks;
     8 
     9 namespace Syspetro.Core.Extensions
    10 {
    11     public class DynamicMethodExecutor
    12     {
    13         private readonly Func<object, object[], object> m_execute;
    14 
    15         public DynamicMethodExecutor(object obj, string method)
    16         {
    17             MethodInfo methodInfo = obj.GetType().GetMethod(method);
    18             this.m_execute = GetExecuteDelegate(methodInfo);
    19         }
    20 
    21         public DynamicMethodExecutor(MethodInfo methodInfo)
    22         {
    23             this.m_execute = GetExecuteDelegate(methodInfo);
    24         }
    25         /// <summary>
    26         /// 调用方法
    27         /// </summary>
    28         /// <param name="instance">实体对象</param>
    29         /// <param name="parameters">参数列表</param>
    30         /// <returns></returns>
    31         public object Execute(object instance, object[] parameters)
    32         {
    33             return this.m_execute(instance, parameters);
    34         }
    35         private static Func<object, object[], object> GetExecuteDelegate(MethodInfo methodInfo)
    36         {
    37             // parameters to execute
    38             ParameterExpression instanceParameter =
    39                 Expression.Parameter(typeof(object), "instance");
    40             ParameterExpression parametersParameter =
    41                 Expression.Parameter(typeof(object[]), "parameters");
    42 
    43             // build parameter list
    44             List<Expression> parameterExpressions = new List<Expression>();
    45             ParameterInfo[] paramInfos = methodInfo.GetParameters();
    46             for (int i = 0; i < paramInfos.Length; i++)
    47             {
    48                 // (Ti)parameters[i]
    49                 BinaryExpression valueObj = Expression.ArrayIndex(
    50                     parametersParameter, Expression.Constant(i));
    51                 UnaryExpression valueCast = Expression.Convert(
    52                     valueObj, paramInfos[i].ParameterType);
    53 
    54                 parameterExpressions.Add(valueCast);
    55             }
    56 
    57             // non-instance for static method, or ((TInstance)instance)
    58             Expression instanceCast = methodInfo.IsStatic ? null :
    59                 Expression.Convert(instanceParameter, methodInfo.ReflectedType);
    60 
    61             // static invoke or ((TInstance)instance).Method
    62             MethodCallExpression methodCall = Expression.Call(
    63                 instanceCast, methodInfo, parameterExpressions);
    64 
    65             // ((TInstance)instance).Method((T0)parameters[0], (T1)parameters[1], ...)
    66             if (methodCall.Type == typeof(void))
    67             {
    68                 Expression<Action<object, object[]>> lambda =
    69                     Expression.Lambda<Action<object, object[]>>(
    70                         methodCall, instanceParameter, parametersParameter);
    71 
    72                 Action<object, object[]> execute = lambda.Compile();
    73                 return (instance, parameters) =>
    74                 {
    75                     execute(instance, parameters);
    76                     return null;
    77                 };
    78             }
    79             else
    80             {
    81                 UnaryExpression castMethodCall = Expression.Convert(
    82                     methodCall, typeof(object));
    83                 Expression<Func<object, object[], object>> lambda =
    84                     Expression.Lambda<Func<object, object[], object>>(
    85                         castMethodCall, instanceParameter, parametersParameter);
    86 
    87                 return lambda.Compile();
    88             }
    89         }
    90     }
    91 }

    如何使用呢:

    1 var service = _serviceProvider.GetService(type);//通过依赖注入实例化实体
    2 
    3 DynamicMethodExecutor dynamicMethodRun = new DynamicMethodExecutor(service, "Run");//调用实体类的 Run()方法
    4 var redata = dynamicMethodRun.Execute(service, null);//redata为方法的返回值
    作者:听枫xl
    本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。
  • 相关阅读:
    5. 图 (算法和数据结构笔记)
    4. 树与二叉树 (算法和数据结构笔记)
    Go第八篇之包的使用
    Go第七篇之规范的接口
    Go第六篇之结构体剖析
    Go第三篇之大话容器
    Go第一篇之轻松入门
    Go第四篇之流程控制
    C简介与环境配置
    程序结构与基本语法
  • 原文地址:https://www.cnblogs.com/xl-tf/p/14515158.html
Copyright © 2020-2023  润新知