了解 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 中?
你应该考虑其余的答案,它们非常准确,我想向你展示的,也许这会帮助你理解语法是,这种查询实际上可以用这样的查询语法来表示:
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表达式检查数组的每个元素是否满足写入的条件,然后最终重新调整满足条件的元素的数组