从LINQ中提取lambda表达式

时间:2016-08-08 09:49:44

标签: c# lambda hyperlink refactoring

我有下一段代码

var query = wordCollection.Select((word) => { return word.ToUpper(); })
                          .Where((word) =>
                                  {
                                      return String.IsNullOrEmpty(word);
                                  })
                          .ToList();

假设我想重构此代码并从Where子句中提取lambda表达式。在Visual Studio中,我只选择此lambda并执行Refactor - >提取方法。通过这样做,我将LINQ修改为

 var query = wordCollection.Select((word) => { return word.ToUpper(); })
                          .Where(NewMethod1())
                          .ToList();

并将NewMethod1()声明为

  private static Func<string, bool> NewMethod1()
  {
      return (word) =>
      {
          return String.IsNullOrEmpty(word);
      };
  }

问题是为什么这个新方法没有任何输入参数,因为委托Func声明NewMethod1()应该有一个字符串输入参数?

2 个答案:

答案 0 :(得分:2)

要获得预期结果,请仅标记此部分String.IsNullOrEmpty(word)并提取方法:

private bool NewMethod(string word)
{
    return String.IsNullOrEmpty(word);
}  

您最初得到的是因为摘录创建了一个返回委托的方法。不是与委托匹配的方法。这是一种返回另一种方法的方法。后者接受字符串参数word并返回bool结果。

确实执行上述操作会将您的代码更改为:

.Where((word) => NewMethod(word))

但您可以安全地将其更改为:

.Where(NewMethod)

旁注:

无需在Linq查询中使用return关键字或任何单行lambda,您可以将查询重构为:

var query = wordCollection.Select(word => word.ToUpper())
                          .Where(word => string.IsNullOrEmpty(word))
                          .ToList();

答案 1 :(得分:0)

你正在选择整个lambda,所以它试图将整个lambda语句提取为一个委托,它接受一个单词并返回一个布尔值 - Func&lt; string,bool&gt;。

重构时,你应该只选择“return String.IsNullOrEmpty(word);”一部分。

此外,您正在以不必要的复杂方式使用lambas。

您可以将LINQ语句重构为:

var query = wordCollection.Select(word => word.ToUpper())
                  .Where(word => String.IsNullOrEmpty(word))
                  .ToList();

甚至对此:

var query = wordCollection.Select(word => word.ToUpper())
                  .Where(String.IsNullOrEmpty)
                  .ToList();