using System.Linq;
using System.Linq.Expressions;
    public static class LambdaExpressionExtensions
    {
        public static Expression<TFunc> And<TFunc>(this Expression<TFunc> expr1, Expression<TFunc> expr2)
        {
            if (expr1.ReturnType != typeof(bool) || expr2.ReturnType != typeof(bool))
                throw new ArgumentException("both lambda expressions must return boolean type");
            if (expr1.Parameters.Zip(expr2.Parameters, (p1, p2) => p1.Type == p2.Type).Any(x => x == false))
                throw new ArgumentException("expr1 and expr2 must have exactly the same parameters");            var p = expr1.Parameters;
            var left = Expression.Invoke(expr1, p);
            var right = Expression.Invoke(expr2, p);
            var expr = Expression.And(left, right);
            return Expression.Lambda<TFunc>(expr, p);
        }
    }
这里在3.5有三个地方出错
1:expr1.ReturnType
2:expr1.Parameters.Zip
3:Expression.Invoke(expr1, p)前两个没有办法解决没什么,我可以注释掉
但第三个方法是必须的谢谢

解决方案 »

  1.   

    var left = Expression.Invoke(expr1, p.ToArray());
    那个是3.5不支持协变造成的,对于System.Collections.Generic.IEnumerable<Expression>接口,需要协变到ReadOnlyCollection<ParameterExpression>,该功能只有4.0以上才提供,不过转换为数组的话,就可以用第二种重载,不需要协变了。
      

  2.   

    更详细请看:
    http://bbs.csdn.net/topics/390303038
    谢谢
      

  3.   

            public static Expression<TFunc> And<TFunc>(this Expression<TFunc> expr1, Expression<TFunc> expr2)
            {
                if (expr1.Body.Type != typeof(bool) || expr2.Body.Type != typeof(bool))
                    throw new ArgumentException("both lambda expressions must return boolean type");
                if (expr1.Parameters.Zip(expr2.Parameters, (p1, p2) => p1.Type == p2.Type).Any(x => x == false))
                    throw new ArgumentException("expr1 and expr2 must have exactly the same parameters");            var p = expr1.Parameters;
                var left = Expression.Invoke(expr1, p.ToArray());
                var right = Expression.Invoke(expr2, p.ToArray());
                var expr = Expression.And(left, right);
                return Expression.Lambda<TFunc>(expr, p);
            }        public static IEnumerable<TResult> Zip<TFirst, TSecond, TResult>(this IEnumerable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst, TSecond, TResult> selector)
            {
                var list1 = first.ToList();
                var list2 = second.ToList();
                for (int i = 0; i < (list1.Count > list2.Count ? list2.Count : list1.Count); i++)
                {
                    yield return selector(list1[i], list2[i]);
                }
            }
      

  4.   

    事实上,Linq弄那么复杂真的闹心啊,Linq出现的目的就是为了简化工作,但是现在却演化得越来越复杂了,让人避而远之。我只用Linq做简单的工作,复杂的用常用方法实现,高效率的就用Emit直接编写,毕竟还需要考虑通用性,不能只会学C#而学这些方法,尽量让自己更换语言后也可以立刻适应。
      

  5.   

    其实linq中所有的操作符我都可以山寨出来,当然性能我就不保证了,以前想搞一个的,这样用.NET 2.0也可以用linq了,但是发现已经有一个叫linqBridge的山寨linq实现了。