代码改变世界

Lambda 表达式构建初级示例(不完整)

2019-09-05 12:23  音乐让我说  阅读(226)  评论(0)    收藏  举报

直接贴代码了:

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

namespace LambdaExpressionTest
{
    class User
    {
        public int Id { get; set; }
        public int? Age { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {

            List<User> userList = new List<User>()
            {
                new User(){ Id = 1, Age = 19 },
                new User(){ Id = 2, Age = 15 },
                new User(){ Id = 3, Age = null },
                new User(){ Id = 4, Age = 16 },
                new User(){ Id = 5, Age = null },
            };
            var resultExp = BuildIsNullOrGreaterThanOrEqualExpression<User>("Age", 18);

            IEnumerable<User> queryResult = userList.Where(resultExp.Compile());
            Console.WriteLine("下面是年龄没有填写,或者填写的年龄大于 18 岁的用户如下:\n");
            foreach (var item in queryResult)
            {
                Console.WriteLine("用户ID:" + item.Id + ",年龄:" + item.Age);
            }

            Console.WriteLine("ok");
        }

        static void TestLambdaExpression<T>()
        {
            //PredicateExpressionBuilder<T> preExpBuilder = new PredicateExpressionBuilder<T>();

            
        }

        static Expression<Func<T, bool>> DateEquals<T>(string memberName, DateTime value)
        {
            var parameter = Expression.Parameter(typeof(T), "p");
            Expression left = Expression.PropertyOrField(parameter, memberName);
            Expression right = Expression.Constant(value.Date);
            if (left.Type == typeof(DateTime?))
            {
                var leftValue = Expression.Property(left, "Value");
                var nullValue = Expression.Constant(null, typeof(DateTime?));
                left = Expression.Condition(
                    Expression.Equal(left, nullValue),
                    nullValue,
                    Expression.Convert(Expression.Property(leftValue, "Date"), typeof(DateTime?))
                );
                right = Expression.Convert(right, typeof(DateTime?));
            }
            var condition = Expression.Equal(left, right);
            return Expression.Lambda<Func<T, bool>>(condition, parameter);
        }

        /// <summary>
        /// Check if two dates are same
        /// </summary>
        /// <typeparam name="TElement">Type</typeparam>
        /// <param name="valueSelector">date field</param>
        /// <param name="value">date compared</param>
        /// <returns>bool</returns>
        public Expression<Func<TElement, bool>> IsSameDate<TElement>(Expression<Func<TElement, DateTime>> valueSelector, DateTime value)
        {
            ParameterExpression p = valueSelector.Parameters.Single();

            var antes = Expression.GreaterThanOrEqual(valueSelector.Body, Expression.Constant(value.Date, typeof(DateTime)));

            var despues = Expression.LessThan(valueSelector.Body, Expression.Constant(value.AddDays(1).Date, typeof(DateTime)));

            Expression body = Expression.And(antes, despues);

            return Expression.Lambda<Func<TElement, bool>>(body, p);
        }

        public static Expression<Func<T, bool>> BuildIsNullOrGreaterThanOrEqualExpression<T>(string propName, object propValue)
        {
            var exp = Expression.Parameter(typeof(T), "t");
            //var propExp = exp.Property(propName);
            Expression propExp = Expression.PropertyOrField(exp, propName);

            var propType = ((MemberExpression)propExp).Type;

            var constant1Exp = Expression.Constant(null, propType);
            var constant2Exp = Expression.Constant(propValue, propType);
            //var left = propExp.Equal(constant1Exp);
            var left = Expression.Equal(propExp, constant1Exp);
            var right = Expression.GreaterThanOrEqual(propExp, constant2Exp);
            Expression body = Expression.OrElse(left, right);
            return Expression.Lambda<Func<T, bool>>(body, exp);
        }
    }
}

 

谢谢浏览!