点燃自己

才发现已成尘

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 :: 管理 ::

动态生成Lambda 表达式学习

Lambda 表达式 使用在LINQ语法中,作为Delegate的进化使用,为了让代码简洁和优雅的呈现,C# Lambda表达式的使用功不可灭,首先,Lambda 在 DLinq 中承担了以往 T-SQL 的部分角色;其次,在数据库设计中,我们往往需要依据外部未知的动态条件组合来查询数据。而问题在于作为一种静态语言,我们显然无法用动态语法或者拼接字 符串的方法来创建一个Delegate/Lambda,那么如何达到类似的目的呢?CodeDom?Emit?或许最佳的选择是 System.Linq.Expressions.Expression。

/*****************************************************************
 *  学习Lambda表达式
 *  author:Kenny
 *  time:20141201
 *  
 * **************************************************************/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace LinqLambdaTest
{
    class Program
    {
        static void Main(string[] args)
        {
            //test 1
            var ints = new int[] { 1,2,3,4,5,6,7,8,9};
            IEnumerable<int> list1 = LambdaOperator.getLambda(ints, 5);

            IEnumerable<int> list2 = LambdaOperator.getLambda2(ints, 7, 5);

        }
    }


    public static class LambdaOperator
    {
        #region 动态生成i=>i>5的表达式
        public static IEnumerable<int> getLambda(int[] ints,int intNum)
        {
            //创建参数
            var parameter = Expression.Parameter(typeof(int), "i");
            //创建常亮 5
            var constant = Expression.Constant(intNum);
            //创建比较表达式i>5
            var bin = Expression.GreaterThan(parameter, constant);
            //获取Lambda表达式
            var lambda = Expression.Lambda<Func<int, bool>>(bin, parameter);
            //通过Compile方法获取Delegate
            var _r = ints.Where(lambda.Compile());

            return _r;
        }
        #endregion

        #region 动态生成ints.Where(i => i > 5 && i <= 7);
        public static IEnumerable<int> getLambda2(int[] ints, int iMax,int iMin)
        {
            //创建参数
            var parameter = Expression.Parameter(typeof(int), "i");

            var con1 = Expression.Constant(iMax);
            var bin1 = Expression.GreaterThan(parameter, con1);

            var con2 = Expression.Constant(iMin);
            var bin2 = Expression.LessThanOrEqual(parameter, con2);
            //组合两个表达式
            var body = Expression.Add(bin1,bin2);
            //并使用 And 完成多个表达式的组装

            //获取Lambda表达式
            var lambda = Expression.Lambda<Func<int, bool>>(body, parameter);

            //通过Compile方法获取Delegate
            var _r = ints.Where(lambda.Compile());
            return _r;
        }
        #endregion

        #region 动态生成ints.Where(i => (i > 5 && i <= 7) || (i == 3));    
        public static IEnumerable<int> getLambda3(int[] ints, int[] args)
        {
            //创建参数
            var parameter = Expression.Parameter(typeof(int), "i");

            var con1 = Expression.Constant(args[0]);
            var bin1 = Expression.GreaterThan(parameter, con1);

            var con2 = Expression.Constant(args[1]);
            var bin2 = Expression.LessThanOrEqual(parameter, con2);

            var con3 = Expression.Constant(args[2]);
            var bin3 = Expression.Equal(parameter, con2);

            //组合两个表达式
            var body = Expression.Add(bin1, bin2);
            //并使用 And 完成多个表达式的组装
            body = Expression.Or(body, bin3);

            //获取Lambda表达式
            var lambda = Expression.Lambda<Func<int, bool>>(body, parameter);

            //通过Compile方法获取Delegate
            var _r = ints.Where(lambda.Compile());
            return _r;
        }
        #endregion

        #region 动态生成ints.Select(i => i % 2 == 0 ? i : 0);
        public static IEnumerable<int> getLambda4(int[] ints, int[] args)
        {
            //创建参数
            var parameter = Expression.Parameter(typeof(int), "i");

            //i%2
            var con1 = Expression.Constant(args[0]);
            var bin1 = Expression.Modulo(parameter, con1);

            // (i%2)==0
            var con2 = Expression.Constant(args[1]);
            var bin2 = Expression.Equal(bin1, con2);

            // IF(((I%2)=0),i,0)
            var bin3 = Expression.Condition(bin2, parameter, Expression.Constant(args[1]));
            //返回i值 或者 默认参数的值 

            //获取Lambda表达式
            var lambda = Expression.Lambda<Func<int, int>>(bin3, parameter);

            //通过Compile方法获取Delegate
            var _r = ints.Select(lambda.Compile());

            return _r;
        }
        #endregion

        #region 动态生成Array.ForEach<int>(ints, i => Console.WriteLine(i));
        public static void getLambda5(int[] ints, int intNum)
        {
            //创建参数
            var parameter = Expression.Parameter(typeof(int), "i");

            //获取 Console.WriteLine MethodInfo
            MethodInfo method = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(int) });

            //创建表达式
            var call = Expression.Call(method, parameter);

            var lambda = Expression.Lambda<Action<int>>(call, parameter);

            //通过Compile方法获取Delegate
            Array.ForEach<int>(ints, lambda.Compile());
            
        }
        #endregion

    }
}


/*
    Lambda 新增了一些委托类型。
 *  1.用于处理无返回数据的action。
 *  
 *  public delegate void Action()
 *  public delegate void Action<T> (T arg)
 *  public delegate void Action<T1,T2>(T1 arg1,T2 arg2)
 *  public delegate void Action<T1,T2,T3>(T1 arg1,T2 arg2,T3 arg3)
 *  
 *  2.用于处理带回数据的Func。
 *  public delegate TResult Func<TResult>()
 *  public delegate TResult Func<T,TResult>(T arg)
 *  public delegate TResult Func<T1,T2,TResult>(T1 arg1,T2 arg2)
 * 
 * 
 * 
 */

 

posted on 2014-12-01 10:46  爱吃糖豆的猪  阅读(1398)  评论(0)    收藏  举报