C# 从LINQ中提取lambda表达式

C# 从LINQ中提取lambda表达式,c#,lambda,hyperlink,refactoring,C#,Lambda,Hyperlink,Refactoring,我有下一段代码 var query = wordCollection.Select((word) => { return word.ToUpper(); }) .Where((word) => { return String.IsNullOrEmpty(word);

我有下一段代码

var query = wordCollection.Select((word) => { return word.ToUpper(); })
                          .Where((word) =>
                                  {
                                      return String.IsNullOrEmpty(word);
                                  })
                          .ToList();
假设我想重构这段代码并从Where子句中提取lambda表达式。在VisualStudio中,我只需选择这个lambda并执行重构->提取方法。通过这样做,我将我的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);
      };
  }
private static Func NewMethod1()
{
返回(字)=>
{
返回字符串.IsNullOrEmpty(word);
};
}

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

要获得预期的结果,只标记这部分
string.IsNullOrEmpty(word)
并提取方法:

private bool NewMethod(string word)
{
    return String.IsNullOrEmpty(word);
}  
您最初得到的是因为提取创建了一个返回委托的方法。不是与委托匹配的方法。它是一个返回另一个方法的方法。后者接受字符串参数
word
,并返回bool结果

确保执行上述操作会将代码更改为:

.Where((word) => NewMethod(word))
但您可以安全地将其更改为:

.Where(NewMethod)
旁注: 无需在Linq查询或任何单行lambda中使用
return
关键字,您可以将查询重构为如下所示:

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

您选择的是整个lambda,因此它试图将整个lambda语句提取为一个委托,该委托接收一个单词并返回一个boolean-Func

重构时,您应该只选择“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();

因为它创建了一个返回委托的方法。不是与委托匹配的方法。您所期望的是一个带有
字符串
参数和
bool
返回类型的方法。它看起来确实不可靠,因为正如上面的人所说,是的,它确实看到了一个不应该编译的函数的表面值,但它返回的是委托,而不是代码的结果,因此,它是如何使用相同的逻辑的,你不能再多做一步使
var query=wordCollection.Select(word=>word.ToUpper()).Where(String.IsNullOrEmpty.ToList()?@SunnyPatel可以这样写,但我更喜欢贴出来的,因为它更简单、更清晰。