理解linq语法

use*_*147 10 .net c# linq syntax

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

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

我对它的语法管理方式感到困惑.它把所有数组放在x?如果是,那么它如何管理x null值?

要么

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

Jup*_*aol 10

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

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;
Run Code Online (Sandbox Code Playgroud)

如果你熟悉SQL,你会发现这种语法更容易阅读,即使你不知道它,这种语法更清晰.

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

关于此代码的简要说明:

  • 正如您所看到的那样,x变量已声明且属于类型string.为什么?因为你的数组是一个字符串数组

  • in test指示源IEnumerable<>迭代-在这种情况下,您的阵列

  • where很简单,只是从数组中选择所有非空字符串

  • 最后选择实际上是数据的投影.

而这一切都等同于您的代码

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

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

基本上lambda是代表的快捷方式,所以你在做什么:

x => !string.IsNullOrEmpty(x)
Run Code Online (Sandbox Code Playgroud)

您正在创建匿名方法,并且该方法正在分配给delegate参数.该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();
Run Code Online (Sandbox Code Playgroud)

如果你谷歌LINQ就像谷歌搜索pol lol网络受到LINQ文章,样本等的困扰.

一个很好的起点是来自微软的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;
   }
}
Run Code Online (Sandbox Code Playgroud)

正如你所看到的委托被称为一个函数(委托是指向函数的指针)对接什么函数??? 您在代码中声明的那个

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

  • X =>是声明一个委托的缩写

  • !string.IsNullOrEmpty(x)这是你的匿名方法主体,你可以看到它满足了它的要求,Func<T, bool>它返回一个bool(用于过滤数组元素的谓词)并作为参数,它收到了generic T,在这种情况下是数组中的字符串

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

test = test.Where(
            (string) x =>
            {
                return !string.IsNullOrEmpty(x)
            })
           .ToArray();
Run Code Online (Sandbox Code Playgroud)

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


Run*_* FS 6

我们可以将声明分开并一次检查一个部分

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

bool Filter(string x){
   return !string.IsNullOrEmpty(x)
}
Run Code Online (Sandbox Code Playgroud)

并根据该函数创建谓词.谓词只是一个委托 - 一个可以传入变量的函数.

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

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

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

test = test.Where(Filter).ToArray(); 
Run Code Online (Sandbox Code Playgroud)

所以通过在你的数组上调用这个扩展方法并传递上面的谓词,你将迭代数组中的所有元素并返回所有那些与谓词匹配的元素(即那些既不是null也不具有空字符串值的元素)

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