了解lambda表达式的工作原理

aqu*_*cks -3 c# lambda

Regex regex = new Regex("^[a-zA-Z0-9,-_ ]{2,12}$");
            return panel1.Controls.OfType<UserControl1>()
.Select(uc => uc.comboBox2).Any(cb => cb.Text == String.Empty);
Run Code Online (Sandbox Code Playgroud)

因为代码是用于验证我正在实现这个但我不知道它是如何工作的以及它在哪里流动.任何人都可以帮我理解这一行吗?

return panel1.Controls.OfType<UserControl1>()
.Select(uc => uc.comboBox2).Any(cb => cb.Text == String.Empty);
Run Code Online (Sandbox Code Playgroud)

Geo*_*ett 7

panel1- 表单上
.controls的控件 - 添加的控件列表panel1
.OfType<UserControl1>()- 只有类型的控件UserControl1
.Select(uc => uc.combobox2)- combobox2属性(每个UserControl1(in panel1))
.Any(cb => cb.Text == String.Empty)- 如果这些comboxbox的任何Text属性为空字符串,则计算结果为true .

所以基本上如果有任何的Text的财产combobox2的财产UserControl1的添加到您的panel1控件为空,则返回true,否则false.


一些解释.Select(uc => uc.comboxbox2).

这就是说调用集合中的每个项目uc.对于每个uc返回值,在右侧创建的值=>.在那种情况下uc.combobox2.想象一下这样做,你会得到一个类型的变量ComboBox(我猜).因为这是在Select方法的上下文中,我们将为每个项目执行此操作.为所有人做这件事意味着你可以根据你的收藏品收集它们UserControl1.

关于方法.Any(cb => cb.Text == String.Empty) 的参数与Any上面的相同,但是它可能会令人困惑,因为"在右边=>"的部分在这种情况下是评估为true或的东西false.该Any方法需要将集合中的每个项目(ComboBox在本例中为a)转换为true或false.如果其中任何一个转换成它,它将返回true true,如果没有,那么它将返回false.


Mat*_*zer 5

  • .Select(...)迭代给定集合中的所有项目,并将新集合投影为IEnumerable<T>项目所选属性或任何对象的位置.

  • .Any(...) 迭代投影集合中的所有项目,并检查至少有一个项目是否满足布尔条件.

更新:

二者Select(...)Any(...)具有一个lambda表达式作为输入参数.在C#中:

uc => uc.comboBox2 
Run Code Online (Sandbox Code Playgroud)

......相当于(还有其他变化):

delegate(UserControl1 uc) { return uc.comboBox2; }
Run Code Online (Sandbox Code Playgroud)

......和:

cb => cb.Text == String.Empty
Run Code Online (Sandbox Code Playgroud)

......相当于:

delegate(ComboBox cb) { return cb.Text == String.Empty }
Run Code Online (Sandbox Code Playgroud)

实际上,除了表达式树之外,lambda表达式只是具有更多函数式编程语法的委托.

延期执行

作为旁注,代码中有一个重点:SelectIEnumerable<T>迭代之前不执行(列表,集合:任何实现).也就是说,执行foreach,调用.ToList()/ .ToArray()或你的情况:.Any(...).

这一点很重要,因为当整个枚举正在延期执行的一部分的对象可能有一个无效状态枚举.

我将使用您的代码给您一个很好的例子:

// First of all we select the combo boxes identifiers:
var selectedItems = panel1.Controls.OfType<UserControl1>()
.Select(uc => uc.comboBox2.ID);

// Then we get the first combobox and we change its identifier:
var firstCombo = panel1.Controls.OfType<UserControl1>().First().comboBox2;
firstCombo.comboBox2.ID = "ChangedID";

// Now we convert the selectedItems to a list with ToList():
List<string> list = selectedItems.ToList();
Run Code Online (Sandbox Code Playgroud)

组合框ID列表的第一项是否具有包含原始ID或更改的组合框的第一个组合框?答案是:它将是改变的,因为Select(...)ToList()被调用时被执行了!