【问题标题】:Lambdaexpression of Linq-query in a variable变量中 Linq 查询的 Lambda 表达式
【发布时间】:2011-05-25 07:14:34
【问题描述】:

如何将要在 linq 查询中使用的 lambda 表达式定义为变量?

例如,当按列表项的不同属性对通用列表进行排序时:

 IList<SampleClass> list = new List<SampleClass>();

 // Populate list
 ...

 list.OrderBy(sampleclass => sampleclass.property1);
 list.OrderBy(sampleclass => sampleclass.property2);

我想在一个变量中定义 lambda 表达式 (sampleclass=> sampleclass.property1) 并调用:

// ??? define expression in a variable ???
Expression expression = sampleclass => sampleclass.property1;

// Sort list by variable expression
list.OrderBy(expression);

提前致谢 托比

【问题讨论】:

    标签: c# linq sorting lambda expression


    【解决方案1】:

    您可以使用Func 重载之一(准确地说是Func&lt;T, TResult&gt;):

    Func<SampleClass, PropertyType> expr = sampleclass => sampleclass.property1;
    list.OrderBy(expr);
    

    PropertyType 是在您的SampleClass 中存储为property1 的变量类型。例如,如果是string,您将使用Func&lt;SampleClass, string&gt;

    【讨论】:

      【解决方案2】:

      如下定义Func&lt;TSampleClass, TPropertyType&gt;

        List<SampleClass> list = new List<SampleClass>();   
        Func<SampleClass, int> expr = (c) => c.SomeProperty;
        _HungerLevel = level;
      
      
        class SampleClass
        {
          public int SomeProperty { get; set; }
        }
      

      【讨论】:

      • 这不起作用:“无法将 lambda 表达式分配给隐式类型的局部变量”
      • @Tobias 你在声明 Func 时使用了 var 关键字吗?
      【解决方案3】:

      你可以使用:

      Func f = sampleClass => sampleClass.Property1; list.OrderBy(f);

      这假定 Property1 的类型是 int。

      【讨论】:

        【解决方案4】:

        你几乎已经完成了。

        参数是从序列中获取项目并给出其键作为结果的任何函数(将在其上完成排序的键)。 lambda 表达式只是此类函数的变体。

        这些符号是可能的:

        list.OrderBy(sampleclass => sampleclass.property1);
        

        Func<SampleClass,string> getKey = sampleclass => sampleclass.property1;
        list.OrderBy(getKey);
        

        string GetKey(SampleClass sampleclass)
        {
            return sampleclass.property1;
        }
        
        list.OrderBy(GetKey);
        

        (我在这里假设property1 是一个字符串,但它当然不是必需的!)

        【讨论】:

          【解决方案5】:

          正如其他人所说,您可以使用Func&lt;T, TResult&gt; 将委托存储到您的函数。

          如果您想使用 Linq-To-Objects 以外的其他东西,那么您也应该将其包含在 Expression 中。类似Expression&lt;Func&lt;T, TResult&gt;&gt;

          【讨论】:

            【解决方案6】:

            如果您只是在谈论 LINQ to Objects,那么这里就不需要 Expressions,因为 Enumerable.OrderBy 的参数是 Func 委托:

            var list = new List<SampleClass> ();
            
            Func<SampleClass, PropertyType1) orderSelector1 = (obj => obj.Property1); // parentheses for clarity
            var sequence1 = list.OrderBy (orderSelector1);
            
            Func<SampleClass, PropertyType2) orderSelector1 = (obj => obj.Property2);
            var sequence2 = list.OrderBy (orderSelector2);
            

            如果要多次赋值,可以让Func返回object

            var list = new List<SampleClass> ();
            Func<SampleClass, object> orderSelector;
            
            orderSelector = (obj => obj.Property1);
            var sequence1 = list.OrderBy (orderSelector);
            
            orderSelector = (obj => obj.Property2);
            var sequence2 = list.OrderBy (orderSelector);
            

            如果您真的想要动态属性选择,即使用string 指定的属性调用OrderBy,则需要Expressions。 this thread 中有很多示例可以让您执行以下操作:

            var list = new List<SampleClass> ();
            var sequence1 = list.OrderBy ("Property1");
            var sequence2 = list.OrderBy ("Property2");
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多