【问题标题】:Is there any way to pass the lambda expression as a variable or argument?有没有办法将 lambda 表达式作为变量或参数传递?
【发布时间】:2012-01-30 11:35:06
【问题描述】:

我需要将 lambda 查询作为参数传递,以下代码是示例,我很想为它找到一个实现,有示例:类似这样的东西:

var expr1 = Where(n => n > 6).OrderBy(n => n % 2 == 0).Select(n => n);
var expr2 = TakeWhile((n, index) => n >= index));

并像这样使用它:

public void UseLambda<T> (IEnumerable<T> source , lambda Expr){

var items= Expr.Compile(source);

foreach(var item in items)
     Console.Writeline(item.ToString());
}

public void Main(){
    List<int> numbers = new List<int> { 10, 24, 9, 87, 193, 12, 7, 2, -45, -2, 9 };
    var expr1 = Where(n => n > 6).OrderBy(n => n % 2 == 0).Select(n => n);
    UseLambda(numbers, expr1);
}

有人知道吗?

【问题讨论】:

    标签: c# .net linq lambda


    【解决方案1】:

    如果你像这样定义你的 LINQ 表达式:

    Func<IEnumerable<int>, IEnumerable<int>> expr1 =
                   l => l.Where(n => n > 6).OrderBy(n => n % 2 == 0).Select(n => n);
    
    Func<IEnumerable<int>, IEnumerable<int>> expr2 = 
                   l => l.TakeWhile((n, index) => n >= index);
    

    你的 UseLambda 方法为:

    public void UseLambda<T> (IEnumerable<T> source 
                              ,Func<IEnumerable<T>, IEnumerable<T>> lambda)
    {
        var items= lambda(source);
    
        foreach(var item in items)
           Console.Writeline(item.ToString());
        }
    }
    

    那么你我认为你有你要找的东西。

    【讨论】:

    • 定义 expr1、expr2 时出错:“System.Collections.IEnumerable”不包含“Where”的定义,并且没有扩展方法“Where”接受第一个参数类型为“System.可以找到 Collections.IEnumerable'(您是否缺少 using 指令或程序集引用?)
    【解决方案2】:

    查看Func(Of T, TResult) Delegate (MSDN)

    using System;
    
    public class LambdaExpression
    {
       public static void Main()
       {
           Func<string, string> convert = s => s.ToUpper();
    
           string name = "Dakota";
           Console.WriteLine(convert(name));   
       }
    }
    

    来自 MSDN

    lambda 表达式的基础类型是通用 Func 委托之一。这使得 可以将 lambda 表达式作为参数传递,而无需将其显式分配给委托。特别是,因为 System.Linq 命名空间中的许多类型方法都具有 Func(Of T, TResult) 参数,因此您可以将 lambda 表达式传递给这些方法,而无需显式实例化 Func(Of T , TResult) 委托。

    编辑

    您的情况的可能解决方案

    static void Main(string[] args) 
    {
        List<int> numbers = new List<int> { 10, 24, 9, 87, 193, 12, 7, 2, -45, -2, 9 };
        Func<IEnumerable<int>, IEnumerable<int>> expr = n => n.Where(n1 => n1 > 6).OrderBy(n1 => n1 % 2 == 0).Select(n1 => n1);
        UseLambda<int>(numbers, expr);
    }
    private static void UseLambda<T>(List<T> numbers, 
                                     Func<IEnumerable<T>, 
                                     IEnumerable<T>> expr) 
    {
        var values = expr(numbers);
        foreach (var item in values) {
           Console.WriteLine(item);
        }
    }
    

    【讨论】:

      【解决方案3】:

      你的意思是这样的:

      public void UseLambda<T> (IEnumerable<T> source , Func<T, bool> where, Func<T, bool> order)
      {
          if(source != null)
          {
              IOrderedEnumerable<T> orderBy = source.Where(where).OrderBy(order);
              foreach (T value in orderBy)
              {
                  Console.WriteLine(value);
              }
          }
      }
      

      所以你可以这样称呼它:

      UseLambda(numbers, x => x > 6, x => x % 2 == 0);
      

      【讨论】:

        【解决方案4】:

        嗯,lambda 只不过是一个委托,所以你可以有这样的方法:

        public void DoIt(IEnumerable a, Action<IEnumerable> performThis)
        {
          performThis(a);
        }
        

        但它的意义在哪里?与其调用应用 lambda 的方法,不如像在代码的最后几行中那样直接调用它?

        【讨论】:

          【解决方案5】:
          public void UseLambda<T>(IEnumerable<T> source, Expression<Func<IEnumerable<T>, IEnumerable<T>>> expr)
          {
              var items = expr.Compile();
          
              foreach (var item in items.Invoke(source))
              {
                  Console.WriteLine(item.ToString());
              }
          }
          
          
          public void Main()
          {
              Expression<Func<IEnumerable<int>, IEnumerable<int>>> expr = s => s.Where(n => n > 6).OrderBy(n => n % 2 == 0).Select(n => n);
              var list = new List<int> { 10, 24, 9, 87, 193, 12, 7, 2, -45, -2, 9 };
          
              UseLambda(list, expr);
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2012-12-27
            • 1970-01-01
            • 2017-07-10
            • 1970-01-01
            • 1970-01-01
            • 2021-12-20
            • 1970-01-01
            相关资源
            最近更新 更多