C#列表理解简介

时间:2020-03-06 14:41:56  来源:igfitidea点击:

如何在C#中执行列表推导?

解决方案

虽然这不是教程,但是下面的代码说明了这一概念:

public List<string> ValidUsers(List<User> users) {
  List<string> names = new List<string>();
  foreach(User user in users) {
    if(user.Valid) {
      names.Add(user.Name);
    }
  }
  return names;
}

我们可以使用LINQ进行类似于列表推导的表达式。这是一个稍微解释一下的网站:

Cwith LINQ中的列表理解

Cwith LINQ第2部分中的列表理解

@伊恩·P

return (from user in users
         where user.Valid
         select user.Name).ToArray();

当我查找如何在C#中执行列表理解时发现了此问题...

当有人说列表理解时,我立即想到了Python。下面的代码生成一个看起来像这样的列表:

[0,2,4,6,8,10,12,14,16,18]

Python的方式是这样的:

list = [2*number for number in range(0,10)]

在C#中:

var list2 = from number in Enumerable.Range(0, 10) select 2*number;

两种方法都被懒惰地评估。

列表推导是一种集合符号,程序员可以在其中描述集合成员必须满足的属性。它通常用于通过对现有集合应用某种类型的组合,变换或者归约函数来基于其他已经存在的集合或者一个或者多个集合创建集合。

请考虑以下问题:我们有一个从0到9的10个数字的序列,并且需要从该序列中提取所有偶数。在Cversion 1.1这样的语言中,我们几乎只能使用以下代码来解决此问题:

ArrayList evens = new ArrayList();
ArrayList numbers = Range(10);
int size = numbers.Count;
int i = 0;

while (i < size) 
{
    if (i % 2 == 0) 
    {
        evens.Add(i);
    }
    i++;
}

上面的代码没有显示Range函数的实现,下面的完整代码列表中提供了该函数。随着C3.0和.NET Framework 3.5的问世,基于Linq的List Comprehension标记现在可供Cprogrammers使用。上面的C1.1代码可以像这样移植到C3.0:

IEnumerable<int> numbers = Enumerable.Range(0, 10);
var evens = from num in numbers where num % 2 == 0 select num;

从技术上讲,通过将对Enumarable.Range的调用移动到生成偶数序列的Linq表达式,可以将上述C3.0代码编写为单行代码。在CList Comprehension中,我通过向该序列应用函数(模2)来减少设置数。这样可以以更简洁的方式生成偶数序列,并避免使用循环语法。现在,我们可能会问自己:这纯粹是语法糖吗?我不知道,但是我会绝对调查,甚至在这里自己问这个问题。我怀疑这不仅是语法糖,而且可以利用底层的monad进行某些真正的优化。

完整的代码清单可在此处获得。