了解 linq 语法

本文关键字:语法 linq 了解 | 更新日期: 2023-09-27 18:35:54

我真的很困惑,无法理解它的内部工作这是 LINQ 语法

string[] test = new test[] { "abc", "", "cd", "", "aa" };
test = test.Where(x => !string.IsNullOrEmpty(x)).ToArray();

我对语法如何管理感到困惑。 它是否将所有数组都放在 X 中? 如果是,那么它如何管理 X 空值?

如果没有,那么测试数组值一个接一个地放在 x 中?

了解 linq 语法

你应该考虑其余的答案,它们非常准确,我想向你展示的,也许这会帮助你理解语法是,这种查询实际上可以用这样的查询语法来表示:

string[] test=new test[]{"abc","","cd","","aa"};
// this is the equivalent to your code
// added explicit type to make it clearer, it's optional
var a = from (string)x in test
        where !string.IsNullOrEmpty(x)
        select x;

如果你熟悉SQL,你会发现这个语法更容易阅读,即使你不知道它,这个语法也更干净。

编译代码时,此查询语法会自动转换为 C# 方法语法,以便生成 IL,因此,如果您不确定 DLL,您将看到方法语法而不是查询语法

有关此代码的简要说明:

  • 如您所见,声明了一个x变量,其类型为 string 。为什么?因为你的数组是一个字符串数组

  • in test指示要迭代的源IEnumerable<> - 在本例中为数组

  • where非常容易解释,它只是从数组中选择所有非空字符串

  • 最后是选择,这实际上是数据的投影。

所有这些都等同于您的代码

现在你可能会问自己...何时应使用一种语法或另一种语法?好吧,它们是等效的,但查询语法运算符是有限的,这意味着大多数操作都是使用方法语法而不是查询语法完成的。我总是尝试编写代码更容易阅读一些代码,如果它是用查询语法编写的,则更容易理解。

关于方法语法,x => ...语法被称为lambda表达式,如果这是您第一次使用它们,它们可能看起来很奇怪,但您最终会喜欢它们。

基本上 lambda 是委托的快捷方式,所以你正在做什么:

x => !string.IsNullOrEmpty(x)

您正在创建一个匿名方法,并且该方法正在分配给委托参数。x代表string variable

这个话题真的很广泛,试图在这里解释它,但我希望这能让你了解背后的原因。

顺便说一句,你可以像这样组合语法:

// this is the equivalent to your code
// added explicit type to make it clearer, it's optional
var a = (from (string)x in test
        where !string.IsNullOrEmpty(x)
        select x).ToArray();

如果你谷歌LINQ就像谷歌搜索色情,哈哈,网络被LINQ文章,示例等所困扰。

一个好的起点是来自Microsoft的 101 个样本

http://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b

编辑

我将尝试模拟 Where 方法,以便您可以获得更好的 lambda 表达式示例

// this is basically the declaration of one overload of the Where method
// the this in the parameter declaration, indicates this is an extension method which will be available to all IEnumerable<> objects
// the Func<T, bool> is the interesting part, it is basically a delegate (as a reminder, the last parameter of the Func object indicates the type that must be returned, in this case is a bool)
// the delegate is simply a pointer to a function 
public IEnumerable<T> Where<T>(this IEnumerable<T> source, Func<T, bool> predicate)
{
   ...some logic


   ... yielding back the reuslts
   foreach(var r in res)
   {
      // here is the delegate in action
       if(predicate(r))
           yield return r;
   }
}

如您所见,委托被作为函数调用(委托是指向函数的指针)对接什么功能???您在代码中声明的那个

  • x => !string.IsNullOrEmpty(x)x指示从 Where 方法传递回外部代码的参数,您可以在其中检查它并使用它来筛选结果

  • x => 是声明委托的缩写

  • !字符串。IsNullOrEmpty(x) 这是匿名方法的主体,如您所见,它满足Func<T, bool>的要求,它返回一个布尔值(过滤数组元素的谓词),并作为参数,它接收泛型T在本例中是数组中的字符串

声明 lambda 表达式的另一种方法是:

test = test.Where(
            (string) x =>
            {
                return !string.IsNullOrEmpty(x)
            })
           .ToArray();

使用此语法很容易表明它们实际上是方法(匿名方法)

我们可以把语句拆开,一次检查一个片段

x => !string.IsNullOrEmpty(x)基本上定义了如下所示的函数

bool Filter(string x){
   return !string.IsNullOrEmpty(x)
}

并基于该函数创建谓词。谓词只是一个委托 - 一个可以在变量中传递的函数。

.Where 是一种扩展方法,为简单起见,可以定义

IEnumerable<T> Where<T>(this IEnumerable<T> sequence,Predicate<T> pred){
   foreach(var elem in sequence){
       if(pred(elem)){
          yield return elem;
       }
   }
}

如果您按照上面定义的函数Filter而不是使用 lambda,您的语句将如下所示

test = test.Where(Filter).ToArray(); 

因此,通过在数组上调用此扩展方法并传递上述谓词,您将遍历数组中的所有元素并返回与谓词匹配的所有元素(即那些既不为 null 也不具有空字符串值的元素)

最后,调用扩展方法.ToArray()该方法将.Where返回的内容(IEnumerable<string>)转换为数组

编辑

阅读这篇文章,你一定会对你有很好的了解......

C# 3.0 新语言功能(第 1 部分)

C# 3.0 新的语言功能(第 2 部分)


它来自 C# 3.0 的扩展方法 + lambda 扩展部分

在此代码中

test=test.Where(x => !string.IsNullOrEmpty(x)).ToArray();

where - 是一种扩展方法

x => !string.IsNullOrEmpty(x) - 是lambda表达式,它是匿名函数的替换

这整个函数检查数组的每个元素...即lamdaba表达式检查数组的每个元素是否满足写入的条件,然后最终重新调整满足条件的元素的数组