C#中使用反射调用参数中包含Lambda表达式的方法

如下代码片断展示了怎样在C#中使用反射调用参数中包含Lambda表达式的方法: GetData(Expression<Func<ExampleEntity, bool>>), 以及根据条件动态选择无参和有参方法:

using System;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;

namespace ReflectCallGenericMethod
{
    class Program
    {
        static void Main(string[] args)
        {
            Assembly assembly = Assembly.GetExecutingAssembly();
            Type typeService = assembly.GetTypes()
                .Where(t => t.IsClass && t.Name == "ExampleService").SingleOrDefault();
            Type typeEntity = assembly.GetTypes()
                .Where(t => t.IsClass && t.Name == "ExampleEntity").SingleOrDefault();

            ParameterExpression paramExp = Expression.Parameter(typeEntity);
            Expression expression = null;
            Type[] types = Type.EmptyTypes;
            object[] parameters = null;

            var condition = Console.ReadLine();

            if (condition.Length > 0)//如果需要过滤数据
            {
                Expression propExp = Expression.Property(paramExp, "ID");
                Expression constExp = Expression.Constant(3);
                expression = Expression.Equal(propExp, constExp);

                Type delegateType = typeof(Func<,>).MakeGenericType(typeEntity, typeof(bool));
                LambdaExpression lambda = Expression.Lambda(delegateType, expression, paramExp);
                types = new[] { lambda.GetType() };
                parameters = new[] { lambda };
            }

            MethodInfo methodGetInstance = typeService.GetMethod("GetInstance");
            MethodInfo methodGetData = typeService.GetMethod("GetData", types);
            
            var instanceService = methodGetInstance.Invoke(null, null);
            string result = methodGetData.Invoke(instanceService, parameters) as string;

            Console.WriteLine(result);
            Console.ReadLine();
        }
    }

    public class ExampleService
    {
        private static readonly Object _mutex = new Object();
        volatile static ExampleService _instance;

        public static ExampleService GetInstance()
        {
            if (_instance == null)
            {
                lock (_mutex)
                {
                    if (_instance == null)
                    {
                        _instance = new ExampleService();
                    }
                }
            }

            return _instance;
        }

        public string GetData()
        {
            return "无参方法被调用";
        }

        public string GetData(Expression<Func<ExampleEntity, bool>> lambda)
        {
            return "有参方法被调用";
        }

        public string GetGenericData<ExampleEntity>()
        {
            return "无参泛型方法被调用";
        }

        public string GetGenericData<ExampleEntity>(Expression<Func<ExampleEntity, bool>> lambda)
        {
            return "有参泛型方法被调用";
        }
    }

    public class ExampleEntity
    {
        public int ID { get; set; }
        public string Name { get; set; }
    }
}

但这种却不能用于有Generic Arguments的方法,如上面代码片断中的GetGenericData方法,有Generic Arguments只能通过GetMember方法迂回的解决,详细参见: https://blogs.msdn.microsoft.com/yirutang/2005/09/14/getmethod-limitation-regarding-generics/